Repository navigation
Conversation
Clicking a bubble's branch action (or "branch in new chat") opens the child session, but its window stayed blank on a spinner until the user switched to another session and back. Root cause: forkBranch takes over the main pane by calling resumeSession(routedSessionId), but resumeSession swaps only the selection — its replaceRoute parameter is accepted and never used, and resumeSession itself never navigates. The URL kept pointing at the PARENT session while the selection pointed at the CHILD, so isRouteSessionMismatch stayed true on every render: ChatRuntimeBoundary suppressed the transcript (suppressMessages) and routedSessionIsLoading never retired. The away-and-back "fix" worked because a sidebar click routes through openSession, which navigates. Fix: navigate to the branch session (replace: true) right after resumeSession in the main-pane takeover path, so route and selection land atomically. The background-branch path is untouched — it opens a tile, which carries no route (and NousResearch#69750 focus-stealing stays fixed).
Related: #95992 addresses the same forkBranch route/selection mismatch by navigating before resumeSession; this PR navigates after it. Please choose one ordering and avoid merging both. |
|
@alt-glitch Thanks for the triage cross-link — I hadn't seen #95992 when I opened this. Having compared the two: Closing this in favor of #95992 (@mashenchina-max, opened 2 days earlier, same root cause, same fix site, tests included). For what it's worth, I independently audited both orderings before closing, and #95992's ordering (navigate before
One heads-up for #95992's review: it touches the same lines of |
fix(desktop): route to the branched session so its window renders
Symptom
Clicking a bubble's branch action (the GitFork "branch in new chat" button, or any path that forks the open chat into a child session) creates the branch correctly, but the branched session's window shows a blank spinner until the user switches to some other session and switches back — only then does the content render.
Root cause
forkBranch(use-session-actions/index.ts) takes over the main pane like this:resumeSessionswaps the selection ($selectedStoredSessionId/selectedStoredSessionIdRef) but never touches the URL — itsreplaceRouteparameter is accepted and ignored, and the function body contains nonavigatecall at all.So after a branch the route still points at the PARENT (
/:parent-id) while the selection points at the CHILD. On every render:isRouteSessionMismatch(routed=parent, selected=child)→ true (chat/index.tsx,route-session-state.ts)ChatRuntimeBoundarygetssuppressMessages = true→ the transcript is suppressedroutedSessionIsLoading→ the session loader never retiresuse-route-resumeeven seesstuckOnRoutedSession(route ≠ selection) and can re-resume the parent, yanking the view backSwitching away and back works because a sidebar click routes through
openSession, which does callnavigate(sessionRoute(id))— that's the only thing the branch path was missing.Fix
One line in the main-pane takeover path of
forkBranch, plus thenavigatedependency:Route and selection now land atomically, so the mismatch suppression never engages.
The background-branch path (branching a session that is NOT currently open) is intentionally untouched: it opens a tile, which carries no route, and navigating there would reintroduce the #69750 focus-stealing bug.
Testing
routes the main workspace to the branch session (branch window renders without a manual away-and-back)— assertsnavigateis called withsessionRoute('branch-stored')+{ replace: true }after a main-pane branch.use-session-actions.test.tsx: 85 passed (was 84)src/app/session/hooks/+src/app/chat/): 144 files, 1557 tests passedtsc -p tsconfig.json --noEmit: cleaneslinton both touched files: clean