fix(desktop): wait for the forked tab before loading its history#3934
Merged
Conversation
added 2 commits
June 10, 2026 20:57
Compaction stores its summary as a user-role message so the model treats it as context, but IsSyntheticUserMessage did not recognize the three fold prefixes. A history reload that races a compaction pass (switch tabs mid-/compact, switch back -> missedTurnDone reload) then rendered the entire fold - tool calls, commands, console digests - as a giant user bubble. Closes #3653
Fork created the new tab, switched to it, and immediately read HistoryForTab - but the tab controller builds in a background goroutine, so the read raced the session resume and returned empty. The ready-event fallback reloads activeTabIdRef, which can still point at the source tab when the build wins the race, so the forked conversation stayed blank. Reuse the waitForTabReady gate the resume path already relies on. Closes #3742
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Root cause
Forkreturns as soon as the new tab exists, but the tab's controller — including the resume of the forked session file — builds in a background goroutine (startTabControllerBuild). The frontend's fork path then didsetActiveTabId+loadSessionDataForTabimmediately, soHistoryForTabran against a tab with no controller yet and returned[]— a reset to an empty transcript.The ready-event fallback was supposed to heal this, but it reloads
activeTabIdRef.current, and when the backend build wins the race against React committing the new active-tab id, the reload targets the source tab — leaving the forked conversation permanently blank, exactly as reported.Fix
Gate the fork path on
waitForTabReady(tab.id)before loading — the same deterministic gateresumeSessionalready uses for tabs it just created. ThesessionLoadSeqguard dedupes any overlapping ready-triggered reload.One-line behavioral change, no backend involvement.
Closes #3742