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
Suspended-session recovery never runs in opencode serve mode: background jobs stay running forever after a server death #62925
After an unclean death of an opencode serve process, durable background jobs (subagent tasks, background shells) stay in running state forever, and the parent sessions keep waiting for tool results that already completed. Restarting the server does not clear them.
Root cause
Suspended-session recovery exists and is durable, but it is only wired for the managed service mode. In packages/server/src/process.ts (dev branch, checked 2026-11-09):
opencode serve boots with no lifecycle, so resumeSuspendedSessions never runs in this mode: pending background rows are never swept, subagent results are never delivered, and shell rows are never released.
Real-world evidence
A long-lived opencode serve deployment that survived several crash/restart cycles accumulated 44 running job rows aged 36.7–138.9 hours, all older than the then-current server process (proving no server had recovered them). 33 were subagent jobs whose child sessions had already completed — their results were never delivered, so the parents sat indefinitely in "waiting for tool result". A deliberate clean restart did not clear the rows.
Reproduction sketch
Start opencode serve.
Run a turn that spawns a subagent (or a background shell task).
Kill the server process (e.g. kill -9) before the job completes or right after the child finishes.
Restart opencode serve.
The job row is still running; the parent session still waits for the tool output even though the child finished.
Expected
At-least-once recovery of suspended sessions should cover serve mode too. The codebase already makes this durability argument for schedules (// Schedules fire from any server process (service, opencode serve, or --standalone); the table holds all their state.) — the same reasoning applies to execution claims and pending background jobs.
Suggested fix
Fork the same sweep on the non-lifecycle boot path (call installRestartContinuity for serve mode as well), keeping the existing per-session resume budget as the runaway guard. If multiple servers can share one storage root, the sweep may additionally need claim takeover coordination; even without it, wiring serve-mode recovery matches what the managed mode already does.
Notes
As an interim workaround we run an external sweeper over the official HTTP APIs (delivering the synthetic completion notification ourselves; duplicates are safely rejected as 409 Conflict, which also makes an upstream fix idempotent with such a sweeper). The primitives are already there — the only missing piece is calling the sweep in serve mode.
Thanks for the detailed report and the deployment data, @rssitnt.
I think this is a duplicate of #56313. It reports the same root cause: installRestartContinuity in packages/server/src/process.ts only runs when a lifecycle is passed, which happens only in service mode. So plain opencode serve never sweeps suspended sessions, and background subagent and shell jobs stay running with no completion delivered to the parent. That thread already discusses the gate and how to fix it, and has picked up another duplicate (#62488).
Possible duplicates and closely related issues, ordered from most to least likely:
If you add your evidence (44 rows, 36.7 to 138.9 hours old, a clean restart not clearing them) and your idempotent 409 sweeper workaround to #56313, it will help there.
The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.
Activity
opencodejr commentedon Nov 9, 2026
Thanks for the detailed report and the deployment data, @rssitnt.
I think this is a duplicate of #56313. It reports the same root cause:
installRestartContinuityinpackages/server/src/process.tsonly runs when alifecycleis passed, which happens only in service mode. So plainopencode servenever sweeps suspended sessions, and background subagent and shell jobs stayrunningwith no completion delivered to the parent. That thread already discusses the gate and how to fix it, and has picked up another duplicate (#62488).Possible duplicates and closely related issues, ordered from most to least likely:
lifecycleguard, same stranded subagent completions.--standalone/opencode servenever settle the interrupted shell tool, so the TUI spins forever #58386: after a hard crash,--standalone/opencode servenever settle the interrupted shell tool. Same missing recovery, seen from the shell tool and TUI side.runningafter the process dies. It includes a 2.2.6opencode servedata point withjobrows stuck after a reboot.If you add your evidence (44 rows, 36.7 to 138.9 hours old, a clean restart not clearing them) and your idempotent 409 sweeper workaround to #56313, it will help there.
The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.