From 562f2ac5a8ca1f928dee4943bdaaf73af825db1f Mon Sep 17 00:00:00 2001 From: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com> Date: Tue, 23 Jun 2026 16:37:16 +1000 Subject: [PATCH] fix(gateway): guard webchat dispatch cleanup --- src/gateway/server-methods/chat.ts | 80 ++++++++++++++++-------------- 1 file changed, 42 insertions(+), 38 deletions(-) diff --git a/src/gateway/server-methods/chat.ts b/src/gateway/server-methods/chat.ts index f64d09377852..f5e5eb8fc65d 100644 --- a/src/gateway/server-methods/chat.ts +++ b/src/gateway/server-methods/chat.ts @@ -5011,7 +5011,7 @@ export const chatHandlers: GatewayRequestHandlers = { errorMessage, }); }) - .finally(async () => { + .finally(() => { activeRunAbort.cleanup(); clearAgentRunContext(clientRunId, lifecycleGeneration); clearActiveChatSendDedupeRun(context.dedupe, activeChatSendDedupeKey, clientRunId); @@ -5019,46 +5019,50 @@ export const chatHandlers: GatewayRequestHandlers = { if (!pendingDispatchLifecycleError) { return; } - const hasActiveRun = hasTrackedActiveSessionRun({ - context, - requestedKey: rawSessionKey, - canonicalKey: sessionKey, - ...(sessionKey === "global" && agentId ? { agentId } : {}), - defaultAgentId: resolveDefaultAgentId(cfg), - }); - if (hasActiveRun) { - return; - } - const persisted = await persistGatewaySessionLifecycleEvent({ - sessionKey, - ...(sessionKey === "global" && agentId ? { agentId } : {}), - event: { - runId: clientRunId, - sessionId: pendingDispatchLifecycleError.sessionId, - lifecycleGeneration, - ts: pendingDispatchLifecycleError.endedAt, - data: { - phase: "error", - startedAt: pendingDispatchLifecycleError.startedAt, - endedAt: pendingDispatchLifecycleError.endedAt, - error: pendingDispatchLifecycleError.error, - }, - }, - }) - .then(() => true) - .catch((persistErr) => { + const persistDispatchLifecycleError = async () => { + const dispatchError = pendingDispatchLifecycleError; + if (!dispatchError) { + return; + } + const hasActiveRun = hasTrackedActiveSessionRun({ + context, + requestedKey: rawSessionKey, + canonicalKey: sessionKey, + ...(sessionKey === "global" && agentId ? { agentId } : {}), + defaultAgentId: resolveDefaultAgentId(cfg), + }); + if (hasActiveRun) { + return; + } + try { + await persistGatewaySessionLifecycleEvent({ + sessionKey, + ...(sessionKey === "global" && agentId ? { agentId } : {}), + event: { + runId: clientRunId, + sessionId: dispatchError.sessionId, + lifecycleGeneration, + ts: dispatchError.endedAt, + data: { + phase: "error", + startedAt: dispatchError.startedAt, + endedAt: dispatchError.endedAt, + error: dispatchError.error, + }, + }, + }); + emitSessionsChanged(context, { + sessionKey, + ...(agentId ? { agentId } : {}), + reason: "chat.dispatch-error", + }); + } catch (persistErr: unknown) { context.logGateway.warn( `webchat session lifecycle persist failed after error: ${formatForLog(persistErr)}`, ); - return false; - }); - if (persisted) { - emitSessionsChanged(context, { - sessionKey, - ...(agentId ? { agentId } : {}), - reason: "chat.dispatch-error", - }); - } + } + }; + void persistDispatchLifecycleError(); }); } catch (err) { activeRunAbort.cleanup({ force: true });