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
serve: rewriting an agent file under a live server poisons sessions — asks return empty text (200 OK, zero tokens) until restart #46245
opencode serve --port 4200 --hostname 127.0.0.1 on Linux
custom project agents in .opencode/agents/*.md (tools as an object map, e.g. read: true)
API use: POST /session/{id}/message with agent: <id>
Reproduction
Start opencode serve in a project that defines a custom agent (.opencode/agents/my-agent.md).
Create a session and send a message with "agent": "my-agent" — answers normally.
While the server is LIVE, rewrite the agent file (any change — e.g. regenerating it from a build step).
Send another message with "agent": "my-agent".
Actual
Every subsequent ask returns HTTP 200 with empty text and zero output tokens, indefinitely. No error is logged server-side, no error surfaces to the client, and the state never recovers. The only remedy is a full server restart (verified: new pid required — killing by a stale pid file while the old listener still holds the port silently keeps the poisoned state).
Expected
Either the rewritten agent definition takes effect, or the previous one keeps serving — not a permanent silent empty-response state.
Why this matters
The empty-200-with-zero-tokens signature is indistinguishable from the provider-error-swallowing symptom already tracked in #41469 (session silently stops on empty LLM response), which makes diagnosing this state much harder than it should be — a poisoned agent looks exactly like a dead provider key. We run a 35-agent fleet against one shared opencode serve (agents generated from a build pipeline), and an agent regeneration mid-flight silently zeroed a whole evaluation run before we traced it to this.
Workaround we adopted: byte-compare before writing agent files (no change, no write) and do a verified restart (real listener resolved via ss, port actually freed, new pid != old pid) after any agent-file change.
Same root cause as a config-load bug I just filed: config/agents/commands are loaded once per project instance and cached for the server lifetime, with no invalidation on file change.
POST /global/dispose (Server.disposeAllInstances…) tears down all instances so the next use re-reads config from disk without restarting the server. Attached clients stay connected; in-flight responses are interrupted. You reported only a full restart recovered the poisoned agent state — if you still have a repro, it's worth checking whether /global/dispose clears it too (untested for this symptom).
POST /instance/dispose for a single project.
The underlying issue is that a failed/rewritten load is never invalidated, so both the empty-response (#46245) and hard-error (#50906) variants persist indefinitely without an explicit dispose.
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.
Activity
Ron-RONZZ-org commentedon Sep 23, 2026
Same root cause as a config-load bug I just filed: config/agents/commands are loaded once per project instance and cached for the server lifetime, with no invalidation on file change.
Two things that may help here:
POST /global/dispose(Server.disposeAllInstances…) tears down all instances so the next use re-reads config from disk without restarting the server. Attached clients stay connected; in-flight responses are interrupted. You reported only a full restart recovered the poisoned agent state — if you still have a repro, it's worth checking whether/global/disposeclears it too (untested for this symptom).POST /instance/disposefor a single project.The underlying issue is that a failed/rewritten load is never invalidated, so both the empty-response (#46245) and hard-error (#50906) variants persist indefinitely without an explicit dispose.
thdxr commentedon Oct 11, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊