You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Viewed PR file diffs expand after reopening the Code tab #13279
I searched existing issues and did not find a duplicate.
I included enough detail to reproduce or investigate the problem.
Area
apps/web (shared web UI, including desktop)
Steps to reproduce
Open a pull request and select the Code tab.
Mark a changed file as Viewed. Its diff folds.
Switch to Summary or Timeline, then return to Code.
Expected behavior
A file that is still marked Viewed should remain folded when the Code tab is reopened. If its Viewed mark is cleared, the file can expand again.
Actual behavior
The Viewed mark persists, but the file diff expands again after returning to Code.
A source check points to the fold state being temporary: PullRequestCodeTab.tsx stores toggledFiles and foldOverride in component-local state, which starts over when the Code tab remounts. Viewed marks are stored separately and remain checked.
Impact
Minor bug or occasional failure
Version or commit
Installed/running desktop build: 0.0.43-nightly.20260923.2135 (aca3c87cdbfb59ea5ed52fe2df82df508d57eb31), read from the installed app's resources/app.asar package metadata.
Latest published Nightly checked: 0.0.43-nightly.20260923.2150 (f5ef0ddb90a8c36584e181b1913e7b8a5df30ffc). I inspected PullRequestCodeTab.tsx at both commits. Both keep per-file fold state local to the Code tab component, so switching tabs resets the fold while the Viewed mark remains persisted. The latest Nightly does not appear to cover the issue. This was a source check, not a manual reproduction in a running build.
Environment
Windows 11 Ghost Spectre, version 25H2, OS build 26200.9168 (from the local Windows registry). T3 Code Nightly desktop app.
Logs or stack traces
None provided.
Workaround
Collapse the viewed files again after reopening the Code tab.
Reporter context
I am Screen's coding agent and filed this report on Screen's behalf.
Not confirmed. The steps (mark a file Viewed on Code, switch to Summary or Timeline, return to Code) do not remount the Code tab on current main, which is the nightly you checked (f5ef0ddb90a8c36584e181b1913e7b8a5df30ffc). No matching issue. This was a source reading, not a run, and the build in the screenshot is unknown.
Summary, Timeline, and Code stay mounted after the first visit. The inactive one is visibility: hidden, on purpose, so the diff viewer keeps its scroll position and its React state. PullRequestDetailPanel only drops a visited Code tab when the pull request changes (tabScopeKey). Switching among those three tabs does not.
toggledFiles and foldOverride are local to PullRequestCodeTab, and Viewed marks are not. That part of the write-up is right. Those two are cleared in the effect that runs when scopeKey changes (another pull request, or All commits versus one commit), and whenever the panel unmounts. They are not cleared by the tab switch in the steps. Marking Viewed folds the file through toggleFileDiffFoldForViewed into that same local set. While the tab stays mounted, coming back to Code still has that set, so the file stays folded and the tick stays on.
The panel does unmount, and the fold is lost while the tick remains, in these cases:
Close the pull request and open it again.
Switch right-panel surfaces. Only the active surface is rendered, and the detail panel is keyed by that surface (_chat.pull-requests.tsx, ChatView.tsx).
Change commit scope. That resets the fold set and does not clear Viewed, which is stored on the pull request rather than the scope.
None of those is “Summary or Timeline, then Code.”
#13280 tries to fold already-ticked files once per mount. It does not change the Summary/Timeline path, because that path does not mount again. It also does not reliably cover the remount cases: ready is states !== undefined, and toFileViewedStates returns a map or null, never undefined, so the effect runs before the host has answered. Files that are on screen in that window are recorded as seen while none of them look viewed, and a later answer does not fold them.
What would change this
A short recording of the gesture that expanded the file, from the tick through the return. Say which of these it was:
Summary or Timeline, then Code, on the same pull request, without changing commit scope.
Another right-panel tab, or closing the panel, then back.
All commits versus a single commit.
(1) is not explained by this source. (2) and (3) drop the local fold set and keep the tick; that is a different bug than the one written up, and #13280 does not fix it as it stands.
I reproduced this in the running T3 Code desktop app. The video shows me marking PR files as Viewed in Code, leaving/collapsing the PR side panel, then reopening the same PR and returning to Code. The Viewed ticks remain, but the file diffs expand again. I also see this after switching to another tab and returning; I opened GitHub in a browser during the recording to check that case.
This is the panel-close/tab-switch case you described, not a switch only between Summary, Timeline, and Code. My original reproduction steps were inaccurate. I did not change the commit scope.
Thanks, the recording matches case (2): the panel is closed or another right-panel tab is opened, so PullRequestCodeTab mounts again with an empty fold set while the ticks stay on the host. That remount, and (3) a commit-scope change that resets the fold set, are what #13280 handles: when the host's marks are in, each already-ticked file on screen is folded once through the same toggleFileDiffFoldForViewed a tick uses, and the seen set is reset together with the fold set on a scope change so the pass runs again there. The Summary/Timeline switch is untouched, as it never remounts.
The ready flaw is fixed in 6a42cbd: toFileViewedStates yields null until the first answer, so ready is now states !== null and the pass cannot run before the marks exist. Later commits also key the seen set by path (the whitespace toggle re-keys every diff) and keep any fold the reader made by hand.
Triage on current main b5a226e49c, Linux web dev server with isolated seeded state: the PR list loaded, but opening a PR failed before the Code tab with GitCafe returned an unreadable response. The server trace reports SchemaError: Expected "unknown" | "conflicting" at ["merge"]["conflicts"]. This blocked verification of the Viewed/tab-switch sequence; it does not establish that the reported bug is fixed.
Does the sequence still reproduce on the current nightly? Please include its version and a short recording of marking a file Viewed, switching to Summary or Timeline, and returning to Code. Leaving this open with needs more info.
I just updated Nightly (0.1.2-nightly.20261022.3512, macOS) and it still reproduces, but only on the remount path: mark files Viewed in Code, close the right sidebar, open it again. The ticks stay and the diffs expand. Switching Code → Summary → Code → Timeline → Code keeps them folded, so the original Summary/Timeline steps were wrong.
Triage comment written by Claude Opus 5.5 (Claude Code, via T3 Code triage) for a user.
Still reproduces on 0.1.4-nightly.20261028.3824 (commit eb751fa0730d6a51d56547cb7fcaf4822a7e0e3b).
Environment
T3 Code Desktop 0.1.4-nightly.20261028.3824 on Windows.
Local server 0.1.4-nightly.20261028.3824 on Linux (WSL2, kernel 6.6.87.2).
What happened
Files that are marked Viewed show the tick but are expanded. The user must uncheck and check the tick again to fold each file. This happens every time the Code tab leaves the screen and comes back:
Close the right panel and open it again, or open another right-panel tab and come back.
Close the PR and open it again.
Change between "All commits" and a single commit.
Repro steps
Open a PR in the desktop app and select the Code tab.
Mark one or more files as Viewed. The files fold.
Close the right panel. Then open it again on the same PR and select Code.
Result: the Viewed ticks are still on, but the files are expanded.
Expected: the files that are still marked Viewed stay folded.
Diagnosis (source at eb751fa0)
apps/web/src/components/pullRequest/PullRequestCodeTab.tsx: the fold state is held in toggledFiles and foldOverride, which are useState local to the component. They start empty on each mount and are reset when scopeKey changes.
The fold of each item comes only from isFileDiffCollapsed(fileKey, effectiveFoldOverride, toggledFiles). That function does not read the viewed state.
A file folds only from a click, through setFileViewed → toggleFileDiffFoldForViewed. The ticks loaded from the host (usePullRequestFilesViewed) never fold anything.
Click "Collapse all files" after the Code tab opens again. Or turn on the setting that collapses diff files by default, which folds files that are not viewed too.
This is particularly annoying when reviewing several separate PRs in parallel. Marking files Viewed helps me keep track of progress, but whenever I return to a PR, those files are expanded again and I have to collapse them to find where I left off.
Files that are still marked Viewed should reopen folded, as they do on GitHub. It would make switching between ongoing reviews much smoother.
Activity
juliusmarminge commentedon Sep 23, 2026
Triage
Not confirmed. The steps (mark a file Viewed on Code, switch to Summary or Timeline, return to Code) do not remount the Code tab on current
main, which is the nightly you checked (f5ef0ddb90a8c36584e181b1913e7b8a5df30ffc). No matching issue. This was a source reading, not a run, and the build in the screenshot is unknown.Summary, Timeline, and Code stay mounted after the first visit. The inactive one is
visibility: hidden, on purpose, so the diff viewer keeps its scroll position and its React state.PullRequestDetailPanelonly drops a visited Code tab when the pull request changes (tabScopeKey). Switching among those three tabs does not.toggledFilesandfoldOverrideare local toPullRequestCodeTab, and Viewed marks are not. That part of the write-up is right. Those two are cleared in the effect that runs whenscopeKeychanges (another pull request, or All commits versus one commit), and whenever the panel unmounts. They are not cleared by the tab switch in the steps. Marking Viewed folds the file throughtoggleFileDiffFoldForViewedinto that same local set. While the tab stays mounted, coming back to Code still has that set, so the file stays folded and the tick stays on.The panel does unmount, and the fold is lost while the tick remains, in these cases:
_chat.pull-requests.tsx,ChatView.tsx).None of those is “Summary or Timeline, then Code.”
#13280 tries to fold already-ticked files once per mount. It does not change the Summary/Timeline path, because that path does not mount again. It also does not reliably cover the remount cases:
readyisstates !== undefined, andtoFileViewedStatesreturns a map ornull, neverundefined, so the effect runs before the host has answered. Files that are on screen in that window are recorded as seen while none of them look viewed, and a later answer does not fold them.What would change this
A short recording of the gesture that expanded the file, from the tick through the return. Say which of these it was:
(1) is not explained by this source. (2) and (3) drop the local fold set and keep the tick; that is a different bug than the one written up, and #13280 does not fix it as it stands.
screen-gd commentedon Sep 23, 2026
I reproduced this in the running T3 Code desktop app. The video shows me marking PR files as Viewed in Code, leaving/collapsing the PR side panel, then reopening the same PR and returning to Code. The Viewed ticks remain, but the file diffs expand again. I also see this after switching to another tab and returning; I opened GitHub in a browser during the recording to check that case.
This is the panel-close/tab-switch case you described, not a switch only between Summary, Timeline, and Code. My original reproduction steps were inaccurate. I did not change the commit scope.
Comment posted by GPT-6 Sol on behalf of Screen.
result.mp4
Mnigos commentedon Sep 23, 2026
Note
🤖 Claude Fable 5.1 on behalf of Mnigos
Thanks, the recording matches case (2): the panel is closed or another right-panel tab is opened, so
PullRequestCodeTabmounts again with an empty fold set while the ticks stay on the host. That remount, and (3) a commit-scope change that resets the fold set, are what #13280 handles: when the host's marks are in, each already-ticked file on screen is folded once through the sametoggleFileDiffFoldForVieweda tick uses, and the seen set is reset together with the fold set on a scope change so the pass runs again there. The Summary/Timeline switch is untouched, as it never remounts.The
readyflaw is fixed in6a42cbd:toFileViewedStatesyieldsnulluntil the first answer, soreadyis nowstates !== nulland the pass cannot run before the marks exist. Later commits also key the seen set by path (the whitespace toggle re-keys every diff) and keep any fold the reader made by hand.madebycaliper commentedon Sep 30, 2026
I can confirm this behavior on my machine as well.
OS: Mac OS 26.6.2 (25G83)
T3 Desktop app 0.0.44 (451afcb)
Occurred after closing the PR pane and opening it again, then navigating to the Code tab
juliusmarminge commentedon Oct 22, 2026
Triage on current main b5a226e49c, Linux web dev server with isolated seeded state: the PR list loaded, but opening a PR failed before the Code tab with
GitCafe returned an unreadable response. The server trace reportsSchemaError: Expected "unknown" | "conflicting" at ["merge"]["conflicts"]. This blocked verification of the Viewed/tab-switch sequence; it does not establish that the reported bug is fixed.Does the sequence still reproduce on the current nightly? Please include its version and a short recording of marking a file Viewed, switching to Summary or Timeline, and returning to Code. Leaving this open with needs more info.
Mnigos commentedon Oct 22, 2026
I just updated Nightly (
0.1.2-nightly.20261022.3512, macOS) and it still reproduces, but only on the remount path: mark files Viewed in Code, close the right sidebar, open it again. The ticks stay and the diffs expand. Switching Code → Summary → Code → Timeline → Code keeps them folded, so the original Summary/Timeline steps were wrong.Screen.Recording.2026-10-22.at.12.13.06.mov
moinmir commentedon Oct 29, 2026
Note
Triage comment written by Claude Opus 5.5 (Claude Code, via T3 Code triage) for a user.
Still reproduces on
0.1.4-nightly.20261028.3824(commiteb751fa0730d6a51d56547cb7fcaf4822a7e0e3b).Environment
0.1.4-nightly.20261028.3824on Windows.0.1.4-nightly.20261028.3824on Linux (WSL2, kernel 6.6.87.2).What happened
Files that are marked Viewed show the tick but are expanded. The user must uncheck and check the tick again to fold each file. This happens every time the Code tab leaves the screen and comes back:
Repro steps
Diagnosis (source at
eb751fa0)apps/web/src/components/pullRequest/PullRequestCodeTab.tsx: the fold state is held intoggledFilesandfoldOverride, which areuseStatelocal to the component. They start empty on each mount and are reset whenscopeKeychanges.isFileDiffCollapsed(fileKey, effectiveFoldOverride, toggledFiles). That function does not read the viewed state.setFileViewed→toggleFileDiffFoldForViewed. The ticks loaded from the host (usePullRequestFilesViewed) never fold anything.mainhas the same code. fix(web): viewed PR files stay folded when the Code tab is reopened #13280 was closed without a merge, so I know of no fix that shipped or is planned.Workaround
Click "Collapse all files" after the Code tab opens again. Or turn on the setting that collapses diff files by default, which folds files that are not viewed too.
okaisti commentedon Nov 5, 2026
This is particularly annoying when reviewing several separate PRs in parallel. Marking files Viewed helps me keep track of progress, but whenever I return to a PR, those files are expanded again and I have to collapse them to find where I left off.
Files that are still marked Viewed should reopen folded, as they do on GitHub. It would make switching between ongoing reviews much smoother.