Skip to content

Desktop app renderer hangs indefinitely on sessions with large message counts #28844

@razzeee

Description

@razzeee

Summary

The desktop app becomes permanently unresponsive ("renderer unresponsive") and eventually crashes (exit code 132) when any loaded session contains a very large number of message parts. The app never recovers — every subsequent launch triggers the same hang because it reloads the offending session on startup.

Observed behaviour

The renderer hangs inside constructMessageRows in a tight SolidJS reactive computation loop. The main process logs show the server starting and becoming ready normally, but the window log shows repeated renderer unresponsive events:

[error] (window) renderer unresponsive { window: 'main', currentURL: 'oc://renderer/index.html' }

The renderer unresponsive sample traces all point to the same location:

at Object.constructMessageRows (session-Bt4AAu7E.js:21129:55)
at Object.fn (session-Bt4AAu7E.js:21586:29)
at runComputation (styles-yJCgQeqq.js:486:22)
at updateComputation (styles-yJCgQeqq.js:469:3)
at createMemo (styles-yJCgQeqq.js:118:3)
at MessageTimeline (session-Bt4AAu7E.js:21584:27)
...

After several minutes the renderer process is killed by the OS with user interaction:

[error] (window) app render process gone {
  url: 'oc://renderer/index.html',
  details: { reason: 'crashed', exitCode: 132 }
}

Sessions involved

The following sessions were present in the database and caused the hang (part counts approximate, from sqlite3 opencode.db):

Session title Part count
Session 1 ~211,000
Session 2 ~183,000
Session 3 ~165,000
Session 4 ~93,000
Session 5 ~86,000

Workaround

Delete the offending sessions directly from the SQLite database:

# Backup first
cp ~/.local/share/opencode/opencode.db ~/.local/share/opencode/opencode.db.bak
# Identify large sessions
sqlite3 ~/.local/share/opencode/opencode.db "
SELECT s.id, s.title, COUNT(p.id) as parts
FROM session s
LEFT JOIN part p ON p.session_id = s.id
GROUP BY s.id
HAVING parts > 50000
ORDER BY parts DESC;"
# Delete offending sessions (cascades to messages and parts)
sqlite3 ~/.local/share/opencode/opencode.db "DELETE FROM session WHERE id IN ('ses_...', ...);"
sqlite3 ~/.local/share/opencode/opencode.db "VACUUM;"

Root cause analysis

constructMessageRows builds message rows synchronously inside a SolidJS createMemo. With tens of thousands of parts this computation never completes within the renderer's event loop budget, causing the process to spin indefinitely. The hang is guaranteed — not flaky — once a session exceeds a certain size threshold.

Suggested fixes

  • Paginate or virtualise message loading — only load and render a window of messages, fetching more as the user scrolls
  • Lazy session loading — don't load all sessions' messages eagerly on startup; load only the active session
  • Circuit breaker — detect sessions above a size threshold and show a warning/truncated view rather than attempting to render all parts

Plugins

None

OpenCode version

1.15.7

Steps to reproduce

  1. Run a long agentic session that accumulates a large number of message parts (observed with 80k–211k parts)
  2. Close and reopen the desktop app
  3. The app loads, the server starts successfully, but the UI never becomes interactive

Screenshot and/or share link

No response

Operating System

Fedora 43

Terminal

No response

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions