anomalyco / anomalyco/opencode
server: crashed run leaves zombie "running" session that blocks all message delivery, plus unrepliable ghost forms
@neriousy is already working on this.
Since Aug 24, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- Avg merge
- 7h 2m
- Merged PRs (30d)
- 384
Description
Summary
When a run dies without cleanup, two sticky failure modes follow: (1) the session stays marked "running" in the server's live registry forever, so every subsequent prompt is enqueued as a steer inbox item that is never delivered; (2) any form the dead run had rendered keeps showing in the TUI but its reply/cancel endpoints 404 — an undismissable ghost form.
Environment
- opencode version: v0.0.0-beta-18050 (beta channel)
- OS: macOS 25.6.0 (Darwin arm64)
- Terminal: tmux / xterm-256color
- Shell: /bin/zsh
- Active plugins: none configured
Reproduction
- A run renders a form (
frm_…), then the run dies without cleanup (observed alongside provider-timeout bursts; service was not restarted). - TUI still shows the form. Submitting it repeatedly logs
POST /api/session/{id}/form/{formID}/reply → 404; cancel also returns 404. Form cannot be dismissed. - Send a new prompt to the session (
opencode2 run -s <id>orPOST /api/session/{id}/prompt, deliverysteer): it lands inGET /api/session/{id}/inboxbut is never delivered.resume_attemptsstays 0. GET /api/session/activereports the session as{"type":"running"}even though its DB row showsidle_outcome=succeededwithtime_idlehours in the past.POST /api/session/{id}/inbox/{inboxID}/steeron a stuck item returns409 ConflictError: "Pending input is no longer queued"even though the item is still listed in the inbox with delivery"steer"— inconsistent state.
Expected Behavior
A dead run's registry entry and forms are cleaned up (or reconciled lazily): prompts either start a new run or fail loudly; ghost forms disappear or can be cancelled.
Actual Behavior
The zombie "running" flag silently swallows every future prompt; the ghost form is stuck in the TUI. Recovery exists only via the undocumented POST /api/session/{id}/interrupt, which users won't find.
Additional Context
-
Workaround that fully unstuck both sessions:
opencode2 api post /api/session/<sessionID>/interrupt opencode2 api delete /api/session/<sessionID>/inbox/<stuckMsgID> # per stuck item # then re-prompt normally (delivery=steer) — run starts and delivers -
One machine had ~15 sessions stuck as
"running"across three projects at once; some undelivered inbox items were days old, suggesting every crashed run leaves permanent residue until a service restart. -
Server log signatures available if useful: repeated
http.status=404on/form/{id}/reply|cancel, plusFormNotFoundErrorunhandled-rejection storms from CLI runs targeting the same sessions.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.