Skip to content

Commit 85e5bb1

Browse files
committed
fix(webapp): improve dead-run friendlyId fallback and swap-race error path
1 parent fe57bc5 commit 85e5bb1

1 file changed

Lines changed: 25 additions & 5 deletions

File tree

apps/webapp/app/services/realtime/sessionRunManager.server.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,19 @@ export async function ensureRunForSession(
123123
// agent as `previousRunId` so its boot gate flips
124124
// `couldHavePriorState` and replays the persisted state instead of
125125
// treating this as a fresh chat. See `chat.agent`'s boot orchestration
126-
// in `packages/trigger-sdk/src/v3/ai.ts`. Falls back to the cuid on
127-
// probe miss (rare — replica miss on a row we just read) so the
128-
// continuation flag still propagates with degraded id fidelity.
129-
priorDeadRunFriendlyId = probe?.friendlyId ?? session.currentRunId;
126+
// in `packages/trigger-sdk/src/v3/ai.ts`.
127+
if (probe?.friendlyId) {
128+
priorDeadRunFriendlyId = probe.friendlyId;
129+
} else {
130+
// Replica miss on a row we just observed via `currentRunId`. Retry
131+
// on the writer so the customer's `runs.retrieve(previousRunId)`
132+
// gets the public `run_*` form rather than the internal cuid.
133+
const writerProbe = await prisma.taskRun.findFirst({
134+
where: { id: session.currentRunId },
135+
select: { friendlyId: true },
136+
});
137+
priorDeadRunFriendlyId = writerProbe?.friendlyId ?? session.currentRunId;
138+
}
130139
}
131140

132141
// 2. Validate config + trigger upfront. Continuation overrides
@@ -457,8 +466,19 @@ export async function swapSessionRun(
457466
select: { currentRunId: true },
458467
});
459468

469+
// Mirror `ensureRunForSession`'s "session vanished" branch: if we
470+
// can't find the row (or it has no current run) on the writer right
471+
// after losing the race, surface as an error rather than handing back
472+
// `callingRunId` with `swapped: false` — that would tell the caller
473+
// it's still the canonical run when in fact we don't know who is.
474+
if (!fresh?.currentRunId) {
475+
throw new SessionRunManagerError(
476+
`Session ${session.id} has no currentRunId after preempted swap`
477+
);
478+
}
479+
460480
return {
461-
runId: fresh?.currentRunId ?? callingRunId,
481+
runId: fresh.currentRunId,
462482
swapped: false,
463483
};
464484
}

0 commit comments

Comments
 (0)