Skip to content

serve: sessions cut by a restart stay "Working" forever unless the server runs with --service #62488

Closed as duplicate

Description

@grok-insider

Description

When opencode serve (without --service) is restarted while a session is working, the session never continues and the UI shows it as "Working" forever.

On shutdown the execution layer keeps the session's execution claim on purpose ("shutdown keeps it for restart continuity", session/execution.ts), so the next server can resume the turn. But only the managed server runs that sweep: installRestartContinuity in packages/server/src/process.ts is called only if (lifecycle), and lifecycle is set only for serve --service. A plain opencode serve --port … (for example under systemd, or any self-hosted server) keeps the claim and never resumes or terminalizes it:

  • time.busy stays newer than time.idle, so clients show the session as working (in our case for days);
  • the session is not in /api/session/active and POST /api/session/{id}/interrupt returns {"interrupted":false}, so there is no way to clear it from a client;
  • the cut turn is never continued.

Same code on dev (73d8832).

Possible fixes: run resumeSuspendedSessions for serve too behind an opt-in (--resume or a config flag, since an unregistered server cannot know it is the only one on the database), or at least terminalize orphaned claims at boot (publish Execution.Interrupted with a non-shutdown reason) so they stop showing as working.

Workaround we use: after the server starts, post the same synthetic message as SessionRestart ("The server restarted while you were working. Continue…", metadata.notice: "restart") to every root session with time.busy > time.idle that is not active.

Plugins

none in the reproduction

OpenCode version

2.2.5

Steps to reproduce

  1. With isolated data directories, run opencode serve --port 4393.
  2. Create a session and prompt it to run sleep 30 with the shell tool, then reply "done".
  3. While the command runs, stop the server with SIGTERM and start it again with the same command.
  4. 60 s later the session still has time.busy > time.idle, is not active, has no "server restarted" notice and never finishes.

Doing the same with opencode serve --port 4394 --service: 20 s after the restart the session has the "The server restarted while you were working" notice and is running again, and at 60 s it is idle with outcome succeeded.

Screenshot

No response

Operating System

NixOS 26.11 (Linux 7.2)

Terminal

none (HTTP API, web UI)

Activity

  1. opencodejr commented on Nov 7, 2026

    @opencodejr

    Thanks for the thorough report and the clear comparison with --service.

    I think this is a duplicate of #56313. It reports the same root cause: installRestartContinuity in packages/server/src/process.ts only runs when the server has a lifecycle, which is only true for serve --service. So a plain opencode serve never resumes or cleans up the execution claims that are deliberately kept on shutdown. That issue also discusses the opt-in approach you suggest and why a server that isn't registered can't safely sweep a shared database. Your details (a session stuck as busy, not listed in /api/session/active, interrupt returning false) and your idea of marking orphaned claims as interrupted at boot would be very useful there.

    Possible duplicates and related issues, ordered by likelihood:

    The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different. For example, reply if you think the fact that a client can't clear the stuck session should be tracked separately.

  2. opencodejr commented on Nov 8, 2026

    @opencodejr

    We didn't hear back, so I'm closing this as a duplicate of #56313. Both have the same root cause: restart continuity (installRestartContinuity) only runs for serve --service, so a plain opencode serve leaves the claims kept at shutdown stranded after a restart.

    Your report adds useful details: the session showing as busy forever, not being listed in /api/session/active, interrupt returning false, and the idea of marking orphaned claims as interrupted at boot. Please add them to #56313, where the opt-in approach is being discussed. #58386 (a stale running tool after a crash on plain serve) is also related.

    If you think the fact that a client can't clear the stuck session should be tracked separately, reply here and we can reopen it. Thanks again for the detailed report and the workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions