diff --git a/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx b/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx index b7bdead6bb..03e4891d3e 100644 --- a/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx +++ b/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx @@ -389,6 +389,78 @@ describe('useRouteResume', () => { expect(resumeSession).toHaveBeenCalledTimes(1) expect(resumeSession).toHaveBeenCalledWith('session-2', true) }) + + it("does not re-resume the old session when the new profile gateway opens before /new commits (#68594)", () => { + const resumeSession = vi.fn(async () => undefined) + const startFreshSessionDraft = vi.fn() + const activeSessionIdRef: MutableRefObject = { current: "runtime-a" } + const creatingSessionRef = { current: false } + const runtimeIdByStoredSessionIdRef = { current: new Map([["session-a", "runtime-a"]]) } + const selectedStoredSessionIdRef: MutableRefObject = { current: "session-a" } + + const { rerender } = render( + + ) + + expect(resumeSession).not.toHaveBeenCalled() + + // Profile switch: clear refs, set freshDraftReady, close profile A gateway. + activeSessionIdRef.current = null + selectedStoredSessionIdRef.current = null + rerender( + + ) + + // Profile B gateway opens before React Router commits /new. + rerender( + + ) + + // Must NOT resume session-a: the fresh draft transition is active. + expect(resumeSession).not.toHaveBeenCalled() + }) }) describe('useRouteResume bounded auto-retry after a failed resume', () => { @@ -602,3 +674,4 @@ describe('useRouteResume bounded auto-retry after a failed resume', () => { expect($resumeExhaustedSessionId.get()).toBeNull() }) }) + diff --git a/apps/desktop/src/app/session/hooks/use-route-resume.ts b/apps/desktop/src/app/session/hooks/use-route-resume.ts index ee135d3303..631f10e007 100644 --- a/apps/desktop/src/app/session/hooks/use-route-resume.ts +++ b/apps/desktop/src/app/session/hooks/use-route-resume.ts @@ -156,7 +156,8 @@ export function useRouteResume({ // we're stranded on a routed session that never loaded. The first two // guard against a transient /:sid re-resume during "new chat" state clears // before the pathname updates from /:sid -> /. - const shouldResume = pathnameChanged || gatewayBecameOpen || stuckOnRoutedSession || explicitlyRequested + const shouldResume = + pathnameChanged || (gatewayBecameOpen && !freshDraftReady) || stuckOnRoutedSession || explicitlyRequested // On a reconnect (gatewayBecameOpen) re-resume even when the route looks // `alreadyActive`: the cached runtime id can be stale once the gateway