Repository navigation
Background service resumes opencode run --standalone sessions after the run was killed, without its permissions or step limit (runaway: 1,660 steps, ~$24) #55076
Description
Description
Description
A session started by opencode run --standalone is resumed by the background service (opencode serve --service) after the run process is gone. The resumed turn runs without the config the run was started with, has no age limit, and is resumed again on every later service start. In my case two headless code-review runs that were killed on Oct 10 were resumed 30 hours later and ran unattended for ~5.5 hours, 1,660 steps in total, costing ~$24 on OpenRouter. I only noticed from the bill.
Related: #51213 (service resumes sessions a live server is still running). Its fix #51215 skips claims whose owner is alive, but says dead owners "behave as before", so it doesn't cover this case: here the owner was dead.
Problems, in the order they happened:
- A killed standalone run leaves its session resumable. The
runclient ended mid-turn (log:InterruptError … POST /api/experimental/session/<id>/wait … http.status=499). The session was never marked as stopped and had no idle event, so it stayed "working" in the sharedopencode.db. - The shared service resumes sessions it never owned. The session ran on the run's private
--standaloneserver, but the background service, which shares the data directory, picked it up on its next start and added "The server restarted while you were working. Continue from where you left off without repeating completed work." A standalone run's session should end with that run. - The resumed turn drops the run's config. The run was started with
OPENCODE_CONFIG_CONTENTsettingagent.build.steps: 25and a bash allowlist ("*": "deny", onlygit log *,git show *,rg *andls *allowed). The resumed sessions ran 861 and 799 steps, and shell commands the allowlist would deny completed:cd <repo> && git show …(105×),git -C <repo> …(112×),sed -n …(9×),git grep …(10×). So a session started with restricted permissions continued with default ones. Anything the original process set up (env, wrappertimeout, an OS sandbox around the CLI) is gone too. - There's no age limit, and it happens on every restart. Resumed 30 h after the run died (Oct 10 → Oct 11), resumed again on the next service start (Oct 12; that attempt failed with
Failed to drain Session … database is locked), and on Oct 13 a service start resumed two more killed standalone sessions from Oct 12. - Nothing visible happens. For headless runs nobody is attached, so a resumed session runs unattended until the service stops.
- (Minor, possibly a separate issue) There's no loop protection: the resumed model re-read the same files up to ~50 times each, the context grew to ~940k tokens, it was auto-compacted, and the loop continued.
Expected:
- When a
--standalonerun exits or is killed, its in-flight turn ends as stopped, not suspended. At minimum, the shared service never resumes sessions created by a standalone server. - If a session is resumed, it keeps the limits it started with (agent steps, permissions), or isn't resumed when they can't be restored.
- Resuming has an age limit and doesn't repeat on every restart.
Plugins
None
OpenCode version
Runs started on 2.0.18. Resumed by the service after it restarted on 2.0.26; seen again on 2.0.26.
Steps to reproduce
What happened:
- Oct 10:
OPENCODE_CONFIG_CONTENT='{"agent":{"build":{"steps":25}},"permission":{"edit":"deny","bash":{"*":"deny","git log *":"allow","git show *":"allow","rg *":"allow","ls *":"allow"}}}' timeout -k 30 900 opencode run --standalone --agent build -m openrouter/z-ai/glm-5.3-flash -f brief.md "Follow the attached brief. Do not modify any files.", twice in parallel. - Both runs ended after one step (the 499 above). Each session had one assistant message and no idle event.
- Oct 11: the background service restarted (around the auto-upgrade to 2.0.26). Both sessions got the restart notice and ran from ~11:25 to ~17:00 UTC: 861 + 799 steps, ~690M input tokens (mostly cache reads).
Minimal repro I expect to show the same thing:
OPENCODE_CONFIG_CONTENT='{"agent":{"build":{"steps":3}},"permission":{"bash":{"*":"deny","ls *":"allow"}}}' opencode run --standalone --agent build -m <model> "<a task that needs many shell steps>"- Kill the
runprocess mid-step. opencode service restart- The session gets the restart notice, runs past 3 steps, and runs shell commands other than
ls.
Operating System
Linux (WSL2, kernel 6.18)
Terminal
N/A (headless opencode run, launched by a script)
Plugins
No response
OpenCode version
No response
Steps to reproduce
No response
Screenshot and/or share link
No response
Operating System
No response
Terminal
No response
Activity
opencode-agent commentedon Oct 13, 2026
Thanks for the detailed report. I reproduced this on 2.0.26, and it still happens on the latest
dev(c5aabae).What I did, using isolated data dirs and a mock OpenAI-compatible model that keeps asking to run
cat /etc/hostname > /tmp/opencode/pwned_<n>.txt:opencode run --standalone --agent buildwithOPENCODE_CONFIG_CONTENTsettingagent.build.steps: 3and an allowlist of"*": "deny"with onlyls *allowed.timeoutwhile the model request was still pending.opencode service startwith the same data directory.The service added "The server restarted while you were working…" to the dead run's session and kept going: 9 steps, three times the limit of 3. All 9
catcommands ran, even though the allowlist denies them. The same command without the kill correctly getsPermission denied: shelland stops after 3 steps. So the limits are lost only when the service resumes the session.The script below reproduces it. Closely related: #51213 (live owners, addressed by #51215, which doesn't cover dead owners) and #51784 (recovery loses the client environment).
Reproduction script (repro.sh)
Run it:
bash repro.shsamvallad33 commentedon Oct 19, 2026
Hi user753,
Did you find what restarted them? I hit the same kind of problem where an agent kept running a command it had been allowed once. If that is what happened on your end, would you want to see something combining memory, authority, and security so an agent cant keep running past a limit nobody set?
Sam