anomalyco / anomalyco/opencode

server: crashed run leaves zombie "running" session that blocks all message delivery, plus unrepliable ghost forms

Open
#44,807 1 comment 0 reactions 1 assignee View on GitHub

@neriousy is already working on this.

Since Aug 24, 2026.

2.0
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

  1. A run renders a form (frm_…), then the run dies without cleanup (observed alongside provider-timeout bursts; service was not restarted).
  2. 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.
  3. Send a new prompt to the session (opencode2 run -s <id> or POST /api/session/{id}/prompt, delivery steer): it lands in GET /api/session/{id}/inbox but is never delivered. resume_attempts stays 0.
  4. GET /api/session/active reports the session as {"type":"running"} even though its DB row shows idle_outcome=succeeded with time_idle hours in the past.
  5. POST /api/session/{id}/inbox/{inboxID}/steer on a stuck item returns 409 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=404 on /form/{id}/reply|cancel, plus FormNotFoundError unhandled-rejection storms from CLI runs targeting the same sessions.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.