anomalyco / anomalyco/opencode

opencode run --attach exits 0 after first tool-call step_finish, drops final text event (1.17.20 + 1.18.4)

Open
#38,661 2 comments 0 reactions 1 assignee View on GitHub

@rekram1-node is already working on this.

Since Jul 24, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

opencode run --attach <url> --format json exits 0 after the first step_finish (reason: "tool-calls") and never emits the second step's text event — even though the server completes the full agentic loop.

Confirmed via server-side SQLite: the --attach session has all 9 parts stored (including the final text from step 2), but the CLI only output 4 events (step 1 only) before exiting.

This makes --attach unusable for any agent that uses tools.

Plugins

None

OpenCode version

1.17.20 (also reproduced on 1.18.4)

Steps to reproduce

1. Start a server with an agent that calls a tool first:

opencode serve --hostname 0.0.0.0 --port 4096

Agent (~/.config/opencode/agents/hello-world.md) — must call a tool then reply:

---
name: hello-world
mode: primary
model: zai-coding-plan/glm-5.2   # any OpenAI-compatible provider reproduces this
tools:
  mcp__my-mcp__get_info: true
---
First call `mcp__my-mcp__get_info`, then reply to the user. Two steps required.

2. Local opencode run works (full 2-step loop, 6 events):

opencode run --agent hello-world --format json --auto --pure "hi"
# → step_start, tool_use, step_finish(tool-calls), step_start, text, step_finish(stop) ✓

3. opencode run --attach is broken (1 step only, 4 events, no text):

opencode run --attach http://<server>:4096 --agent hello-world --format json --auto --pure "hi"
# → step_start, tool_use, step_finish(tool-calls), [exit 0] ✗

Reproduces on loopback (127.0.0.1:4096 from inside the same container) — not a networking issue.

Server-side proof (the key evidence)

After the --attach call above, querying the session in the server's SQLite DB (opencode.db) shows all 9 parts including the final text:

parts stored for attach session:
  [0] text      "hi"                    (user)
  [1] step-start                        (step 1)
  [2] reasoning
  [3] tool       my-mcp__get_info
  [4] step-finish
  [5] step-start                        (step 2 ← server started it)
  [6] reasoning
  [7] text      "Here is the info..."   ← final response EXISTS in DB
  [8] step-finish

The server completed step 2 and stored the text, but the CLI exited before consuming those events.

Session token counts confirm: output: 66 tokens (attach) vs output: 65 (local baseline) — the model generated similar output in both cases.

Suspected code location

packages/opencode/src/cli/cmd/run.ts, the event loop break condition (~line 789):

if (
  event.type === "session.status" &&
  event.properties.status.type === "idle"
) {
  break   // ← exits before step 2 events arrive
}

In --attach mode the server appears to emit session.status: idle between step 1 and step 2; the CLI treats it as turn-complete and exits. Local mode doesn't hit this (in-process event timing differs).

Operating System

Linux x86_64 (Docker containers, node:20-slim based)

Terminal

Non-interactive (--format json piped to stdout, no TTY)

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.