diff --git a/apps/web/app/api/chat/stop/route.ts b/apps/web/app/api/chat/stop/route.ts index c4886dca8aa..a19327445d6 100644 --- a/apps/web/app/api/chat/stop/route.ts +++ b/apps/web/app/api/chat/stop/route.ts @@ -45,5 +45,6 @@ export async function POST(req: Request) { if (aborted || abortedChildren > 0) { trackServer("chat_stopped"); } + return Response.json({ aborted, abortedChildren }); } diff --git a/apps/web/app/components/chat-panel.tsx b/apps/web/app/components/chat-panel.tsx index 711d9f698be..fff0c343c66 100644 --- a/apps/web/app/components/chat-panel.tsx +++ b/apps/web/app/components/chat-panel.tsx @@ -1849,10 +1849,12 @@ export const ChatPanel = forwardRef( reconnectAbortRef.current?.abort(); setIsReconnecting(false); - // Stop the server-side agent run and wait for confirmation so the - // session is no longer in "running" state before we stop the - // client-side stream (which may trigger queued message flush). - const stopKey = subagentSessionKey || currentSessionId; + // Read from refs to avoid stale closures — sessionIdRef is updated + // synchronously in handleEditorSubmit, so it's always current even + // if React hasn't re-rendered with the new state yet. + const sk = subagentSessionKeyRef.current; + const sid = sessionIdRef.current; + const stopKey = sk || sid; if (stopKey) { try { await fetch("/api/chat/stop", { @@ -1861,17 +1863,17 @@ export const ChatPanel = forwardRef( "Content-Type": "application/json", }, body: JSON.stringify( - subagentSessionKey - ? { sessionKey: subagentSessionKey } - : { sessionId: currentSessionId }, + sk + ? { sessionKey: sk } + : { sessionId: sid }, ), }); } catch { /* ignore */ } } - // Stop the useChat transport stream (transitions status → "ready"). - void stop(); - }, [currentSessionId, subagentSessionKey, stop]); + // Stop the useChat transport stream (transitions status → "ready"). + void stop(); + }, [stop]); // ── Queue handlers ──