Repository navigation
Closed as not planned
Closed as not planned
Copy link
Description
Description
OpenCode Backend Bug: Tool Execution Hangs and Event Loop Blockage
Bug Description
The OpenCode backend experiences two severe stability issues when executing the bash tool:
- Indefinite Hangs (Ghost Processes): When a fast-exiting command (like
jq,echo, or commands that crash instantly) is executed, the session sometimes hangs permanently. The tool remains in therunningstate in the UI indefinitely, even though the underlying OS process has already terminated. - Event Loop Blockage (
database is locked): When a command emits thousands of lines of output very quickly (e.g.,npm install, a largegrep, orcaton a massive file), the backend Node.js process chokes, leading toSQLiteError: database is lockedexceptions. This drops events and causes the session to hit the 15-second heartbeat timeout.
Root Causes
- Race Condition in
CrossSpawnSpawner:CrossSpawnSpawnerrelies strictly on thespawnevent to resolve theEffectpromise. If a process exits so fast that thespawnevent is omitted or misordered by the OS/Node bindings, theresume()callback is never called, leaving the execution promise blocked forever. - Synchronous Metadata Writes: The stream processor (
Stream.runForEach) invokesctx.metadata(...)for every single chunk emitted by the process stdout/stderr. This queues thousands of synchronousdb.insert().run()calls on the main thread, locking the database and completely starving the event loop. Furthermore, when the process does exit, the background stream fiber is instantly interrupted, which silently drops any output chunks still buffered in memory.
Steps to Reproduce
Issue 1: Indefinite Hangs
- Dispatch multiple fast-exiting tools at once, or run a single incredibly fast tool like
jq '{test: 1}'. - Notice that randomly, the UI gets stuck on "running command".
- Check
ps aux | grep jq— the process is dead, but the backend is still waiting.
Issue 2: DB Locking and Event Loop Starvation
- Run a command that outputs massive amounts of text instantly, e.g.,
cat /dev/urandom | head -n 100000 | base64orfind /. - Watch the logs fill with unhandled
SQLiteError: database is locked. - The UI will eventually stall and the session will crash or timeout.
Expected Behavior
- Fast-exiting processes should reliably resolve their execution promise regardless of event ordering.
- High-volume output commands should throttle their metadata updates (e.g., every 250ms) to avoid locking the single-writer SQLite database and choking the Node event loop.
- The stream fiber should fully drain its buffered output before completing the tool execution, ensuring no trailing output is truncated.
OpenCode version
1.3.13
Metadata
Metadata
Assignees
Labels
No labels
Activity
github-actions commentedon Apr 4, 2026
This issue might be a duplicate of existing issues. Please check:
Please review those issues and, if your report covers the same root cause or adds new information, consider commenting there instead of opening a new issue. If your report is genuinely distinct (e.g., the race condition in spawn event ordering is a separate root cause from the background child pipe issue in #20902), please clarify that distinction so maintainers can track them separately.
t2174: feat(opencode): weekly DB maintenance routine (r913) for SQLit…
t2174: feat(opencode): weekly DB maintenance routine (r913) for SQLit…
t2174: feat(opencode): weekly DB maintenance routine (r913) for SQLit…
github-actions commentedon Jul 4, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.