Repository navigation
Description
Summary
On OpenCode Desktop v2 (opencode v2.0.29, Windows), switching from a long session to another session and then back drops the timeline to the bottom of the conversation instead of restoring the scroll position left when the session was last active. The reading position is lost on every switch.
Follow-up to #55114 (closed as not planned for Desktop 1.18.x, with the instruction to open a new issue with a v2 version if it still reproduces).
Environment
- opencode version: v2.0.29 (
opencode --version) - OS: Windows 11 (Microsoft Windows NT 10.0.26200.0, x64)
- Terminal: Unavailable: desktop app UI session (terminal environment variables are not set)
- Shell:
C:\WINDOWS\system32\cmd.exe - Install/channel: OpenCode Desktop, release build (v2)
- Active plugins:
oh-my-openagent@latest
Reproduction
- Open a session with a long conversation (long enough that the timeline scrolls).
- Scroll up so the viewport rests in the middle of the conversation, away from the bottom.
- Switch to a different session.
- Switch back to the original session.
- Observe: the timeline is at the bottom of the conversation instead of the position left in step 2.
Expected Behavior
The timeline should return to the scroll position left when the session was last active, and should only follow to the bottom when the user left it at the bottom (or new content is being appended).
Actual Behavior
The timeline jumps to the bottom on every switch back. No error is shown; the previously read position must be found again by scrolling manually. Occurs consistently and does not require new messages to arrive in the session.
Additional Context
- Previous report with the same symptom: desktop: session scroll position is lost when switching tabs and back (returns to bottom) #55114 (Desktop 1.18.34/1.18.35, macOS; closed as not planned; also confirmed there on Desktop v2 2.0.28 by another reporter).
- Earlier related reports: [Desktop] Tab switch resets scroll position — returns to bottom instead of where you left off #42213, In the OpenCode macOS app, switching away from a tab and then back to it automatically scrolls the page to the bottom; please do not move my reading position. #45212, Chat visually disappears (scrollTop resets to 0 after tab switch) #35377, Scope terminal sidebar and session scroll state to each tab #44152 (desktop); bug: scroll position lost when navigating between parent and child sessions in web app #42806 (web, parent/child sessions, open).
- Earlier fix attempts closed without merging: fix(app): restore session timeline scroll position after tab switches #48125, fix(app): preserve session scroll position #33875.
- Source notes from desktop: session scroll position is lost when switching tabs and back (returns to bottom) #55114: session tabs are router routes, so switching unmounts the previous session's timeline (its
scrollTopis discarded); the timeline follow state defaults topinned: true, so a remounted timeline lands at the bottom; the window-scoped tabs store persists titles/panes/closed tabs but no scroll offset or pin state. - Frequency: 100% reproducible, any session with a scrollable timeline.
- Workarounds tried: none found; manual scrolling back each time.
- Related open requests: [FEATURE]: open a session at the start of the last message instead of scrolled to the bottom #54572, [FEATURE]: home returns to where end left a scrolled-up reader #53629.
Activity
opencode-agent commentedon Oct 15, 2026
Thanks for the detailed report and for linking back to #55114.
I couldn't reproduce this here because it happens in the Desktop app's session timeline, and this sandbox can't run the desktop app or a browser. A maintainer with the Desktop app will need to confirm it.
The current code matches what you describe. The timeline's "follow the bottom" state starts out pinned, and it treats a session it wasn't last tracking as pinned too. I didn't find anything that saves or restores each session's scroll position, so switching back probably lands at the bottom. I haven't seen it happen myself, though.
Related issues, most closely related first:
khalidshimul commentedon Oct 20, 2026
Still reproduces on OpenCode Desktop v2
2.0.32(Windows), so this is not fixed as of the current release. Adding my confirmation as the v2 report requested in #55114.Environment
2.0.32(Desktop release build)Microsoft Windows NT 10.0.26200.0, x64C:\WINDOWS\system32\cmd.exe%LOCALAPPDATA%\Programs\@opencodedesktop, installed 2026-10-19)Reproduction
Expected Behavior
The timeline returns to the scroll position it was left at, and only follows to the bottom when it was already at the bottom.
Actual Behavior
The timeline jumps to the bottom on every switch back. 100% reproducible, no new messages need to arrive, and no error is shown.
Additional Context
scrollTopis discarded), and the remounted timeline defaults topinned: true, which lands it at the bottom.Echo3clipse commentedon Oct 28, 2026
The issue still occurs on OpenCode Desktop 2.2.0.
I would like to add: This doesn't only pertain to the output timeline scroll position, which always jumps to the bottom, but it also pertains to the input text field scroll position.
So if I add a lot of text in the input field (which is tiny as it is) and switch sessions and back, the input text field scroll position always jumps to the top again.
So both scroll positions should be remembered in a session on desktop: output and input. Right now it's a UX nightmare.
magiccodelab commentedon Nov 3, 2026
Confirming this on v2.2.5 (current master
1bf08ae) and adding the code paths, because the Desktop renderer uses the samepackages/appsession timeline as the web app — this is not specific to Electron or to the Desktop tab strip.Repro
It does not depend on new messages arriving. A 356-message session makes it very visible.
Expected
Restore the reading position. Only follow the newest content if the session was at the bottom when it was left.
Actual
Every switch back re-pins to the bottom.
Root cause
packages/app/src/session/timeline/interaction.ts:312-331: asessionKeychange callspin(); aparams.idchange callspin()+scrollToEnd(). Both fire on a normal tab switch.interaction.ts:21,50:followis a single{ sessionKey, pinned }slot.pinned()returnstruefor any session other than the last tracked one, so an "unpinned" state is not remembered per session.packages/app/src/session/timeline/virtualizer.tsx:257-259: the comment states that route navigation detaches and reattaches the scroll element, which drops its offset.virtualizer.tsx:288-296: on reattach, ifpinned, it callsscrollToEnd();initialOffsetisMAX_SAFE_INTEGERwhen pinned, otherwise0. There is no saved offset to restore.packages/app/src/session/timeline/cache.tsand the virtualizer cache keep measurements and disclosure state, but not scroll position.packages/app/src/session/screen.tsx:431swaps cached timeline views through a<Show>, so the previous scroller is detached while another session is routed.Possible fix
scrollTopis fragile because virtualized row measurements change.follow/pinnedper session instead of one slot, or persist it in the existinglayout.sessionViewscroll map.pin()/scrollToEnd()on session change. Pin on first open, or only when the session was left at the bottom.Related: #59493 (duplicate report). I can test a patch against this branch if that helps.
yassine-safraoui commentedon Nov 4, 2026
+1 this, it's super annoying when reviewing some response that take a lot of time to churn through
sathwick-p commentedon Nov 4, 2026
+1 Yes, can we please get this fixed