Repository navigation
Description
Summary
OpenCode Desktop (Windows) renderer becomes permanently unresponsive on startup when it auto-restores a tab pointing to a very large session. Stack samples show an infinite layout loop between the virtualized message list's auto-scroll (scrollToEnd → scrollToIndex) and resizeItem → Map.forEach → reactive update → scrollToEnd again. The window thread never yields, so Electron fires renderer-unresponsive repeatedly and shows the "OpenCode is not responding" dialog. Reproduced on 2.1.2 and 2.1.3 (Electron 44.9.1 / Chrome 152).
Environment
- opencode version: desktop app 2.1.3 (also reproduced on 2.1.2 before updating); CLI 2.1.3
- OS: Windows_NT 10.0.19045 (win32 x64)
- Terminal: Unavailable: desktop Electron app (no terminal involved)
- Shell: PowerShell 5.1
- Install/channel: latest (packaged desktop install, auto-updater)
- Active plugins: none found in config
Reproduction
- Use OpenCode Desktop with a long-running session containing a very large number of message parts (session that accumulated a ~7 MB server log).
- Close and reopen the desktop app; it restores the tab via
localStoragekeyopencode.desktop.window.<windowId>.last-active-url, which points at/server/<server>/session/<ses_…>(the large session). - Within ~10–20 s of window load, the renderer stops responding; the "OpenCode is not responding" dialog appears (Reabrir / Exportar logs / Continuar aguardando).
- "Reabrir" reloads the same restored tab and the loop re-triggers.
Expected Behavior
The session view should render (even if slowly), and/or the auto-scroll logic should not feed back into item-resize observers in an unbounded loop. There should also be a way to disable session/tab restore on startup.
Actual Behavior
UI thread is stuck in a synchronous loop; the window is dead until killed. Exported window.log reports renderer unresponsive with these samples (identical shape on 2.1.2 and 2.1.3, only bundle names differ):
[error] (window) renderer unresponsive { currentURL: 'oc://renderer/index.html' }
<4> at Te (oc://renderer/assets/route-*.js:9:58274)
<3> at Array.Re (main-*.js:2:12237)
at Object.active (route-*.js:10:9062)
at n (route-*.js:9:52592)
at Object.scrollToFn (route-*.js:9:54800)
at w._scrollToOffset (esm-*.js:1:20352)
at w.scrollToIndex (esm-*.js:1:18902)
at Proxy.scrollToEnd (esm-*.js:1:19335)
at Te (route-*.js:9:58258)
<1> at Map.delete (<anonymous>)
at Fg.F.resizeItem (route-*.js:9:55294)
at route-*.js:9:58629
at Map.forEach (<anonymous>)
at route-*.js:9:58600
<1> at Fg.F.resizeItem (route-*.js:9:55184)
... (same cycle)
Total Samples: 14
The pattern scrollToEnd → scrollToIndex → resizeItem → reactive update → scrollToEnd repeats across every sample, indicating an unbounded render/layout feedback loop in the virtualized message list.
Additional Context
- Fully reproducible on every start while the large session is the restored tab; the app becomes usable only after clearing the restore state.
- Workarounds tried: holding Shift at launch (does not prevent restore); updating 2.1.2 → 2.1.3 (loop persists); clearing/replacing the
Local Storagefolder finally stops the freeze. - Suggest: (a) break the loop (e.g. guard auto-scroll while resizing / rAF-scheduled scroll, item-size measurement caching), (b) add a setting or startup flag to disable tab/session restore, (c) a fallback to open a new-session tab if the restored route triggers the unresponsive watchdog.
- Debug log bundles (window.log / main.log / renderer.log samples) available on request; they contain full
renderer unresponsivestacks and netlogs (several privacy-redacted identifiers).
Activity
opencode-agent commentedon Oct 22, 2026
Thanks for the detailed report and the stack samples. I couldn't reproduce this here: it happens in the desktop app's renderer, and this sandbox can't run the desktop app or build a session large enough to trigger it, so a maintainer with the desktop app will need to look.
The samples point at the auto-scroll-to-end logic in the session timeline's virtualized list. It looks like it keeps triggering item re-measurement in a loop when the session is pinned to the bottom, but I haven't confirmed that by running it.
If you can, attaching the exported
window.log/renderer.log, plus a rough count of messages and tool calls in the affected session, would help whoever picks this up. Until then, clearing the window's restore state (as you found) is the workaround.Hona commentedon Oct 30, 2026
Fixed in v2.2.1+ (#60034). Under fractional OS display scaling (125%/150%/175%) or desktop zoom, Chromium stops scrolling ~1-2px short of
scrollHeight - clientHeight, which wedged the timeline virtualizer cold-mount settle microtask loop (scrollToEnd<->resizeItem) on session open/restore. Please update to v2.2.1 or newer (v2.2.2 is current) and let us know if you still see this.