Skip to content

serve: rewriting an agent file under a live server poisons sessions — asks return empty text (200 OK, zero tokens) until restart #46245

Closed as not planned

Description

@xfnwfpho1

Environment

  • opencode 1.18.23 and 1.18.25 (verified on both)
  • 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

  1. Start opencode serve in a project that defines a custom agent (.opencode/agents/my-agent.md).
  2. Create a session and send a message with "agent": "my-agent" — answers normally.
  3. While the server is LIVE, rewrite the agent file (any change — e.g. regenerating it from a build step).
  4. 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.

Related

Happy to provide more detail (request/response captures, agent frontmatter, server logs) if useful.

Activity

  1. Ron-RONZZ-org commented on Sep 23, 2026

    @Ron-RONZZ-org

    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:

    1. 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).
    2. 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.

  2. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions