Repository navigation
Description
Summary
In Code Mode, the model intermittently writes its tool call as plain
assistant text (Anthropic-style <invoke> / <parameter name="…"> markup)
instead of emitting a structured tool call. OpenCode does not parse or execute
that text: no tool part is created, the step finishes with idle, and the
intended tool call is silently lost. The session then stalls and only proceeds
when another turn is issued.
Environment
- opencode version: 2.0.32 (latest release, Oct 16 2026)
- OS: Linux 6.18.54.1-microsoft-standard-WSL2 x86_64 GNU/Linux
- Agent:
build, Code Mode - Provider/model:
opencode/big-pickle, variantdefault - Plugins: none (no
opencode.json/.opencode/opencode.json)
Reproduction
- Run a long multi-step
buildtask in Code Mode. - Observe the last assistant message of a step. Instead of a structured tool
call it contains prose followed by raw call markup, and notoolpart.
Concrete transcript from session ses_ea9cd281cffe9pJbrBsyPQSpup (read-only
query against ~/.local/share/opencode/opencode.db):
10:50:33 assistant [text, TOOL:grep:completed, TOOL:shell:completed] <- real calls, fine
10:50:36 assistant [text*MK*] <- only text, NO tool part
10:50:39 idle <- step ends
10:52:03 user <- new turn needed to continue
The text*MK* message body looks like:
Let me look at `get_deployed_stems` and `_refresh_deployed_flag` — this is the core of the bug.
<parameter name="path">/root/zorq-sigma-bridge/app/…
The read it asks for never runs in that step; the same read is repeated and
executed only in the following turn.
Expected Behavior
The intended tool call should not be dropped. Either:
- parse the text-form call and execute it (a text fallback parser), or
- immediately re-prompt the model to emit a real tool call instead of ending
the step and leaving the session idle,
and in all cases surface why the step ended.
Actual Behavior
No tool part is created, the step ends with idle, the call is lost, and the
session needs an extra turn to move on — effectively stalling long agent runs.
Occurrences (text parts containing call markup, excluding transcripts where the
agent itself quotes the markup while discussing it):
| session | text-parts with markup | window |
|---|---|---|
ses_eaea51780ffex7kzsnKf1s1lak |
7 | 19 Oct 23:02 |
ses_eaa3947b1ffeexwKdX3g4RKT3t (fork of the above) |
36 | 19 Oct 23:02 → 20 Oct 01:04 |
ses_ea9cd281cffe9pJbrBsyPQSpup (new session) |
6 | 20 Oct 10:40 → 10:54 |
9 other sessions on the same provider/model/version never produced it, so it
is intermittent and session-dependent.
Additional Context
- Prompt-level workarounds do not help. A repo
AGENTS.mdrule was added
that forbids emitting this markup (initially listing the forbidden tokens as
examples, then rewritten to avoid mentioning them at all). The rules were
removed from the instructions before the last reproduction: session
ses_ea9cd281…was created at 01:05 on 20 Oct, after the instruction files
were already clean, and still reproduced at 10:40–10:54. Its recorded
instruction blob contains no markup tokens. - Not a skills/plugins issue. All installed skill files were scanned for
<invoke/<parameter name=/antml:/function_calls— no matches;
no plugins are configured. - The markup always appears in the final assistant message of a step,
immediately before theidlemessage, and is interleaved with normal
structuredtoolcalls earlier in the same step. - A separate issue in the same environment is a recurring
AI.Error: Rate limit exceeded(provider.quota,FreeUsageLimitError) on
the free tier; it is independent of the markup problem and is not
contributing to the reports above.
Related
- MiMo V2.5 outputs tml:function_calls as plain text instead of structured tool calls #43385 — model outputs function-call syntax as plain text (closed against 1.x, invitation to re-file for 2.0)
- Raw <tool_calls> markup in reasoning breaks tool calls on several models #25644 — raw
<tool_calls>markup in reasoning breaks tool calls - Empty bash tool arguments {} can still be submitted and interrupt the session #27871 — invalid tool arguments leave the session interrupted
Activity
opencode-agent commentedon Oct 20, 2026
Thanks for the detailed report and the database evidence, @untitledds!
What happens here is that Big Pickle sometimes writes its tool call as plain
<invoke>/<parameter>text instead of making a real tool call. OpenCode doesn't add that markup itself: neither the Code Mode instructions nor the session history contain it. The response therefore arrives as text only with a normal stop. OpenCode currently treats a text-only reply as the end of the turn, and nothing in 2.x converts tool calls written as text into real ones.What you're asking for is new behaviour: when a reply contains tool-call markup but no real tool call, either run it through a text fallback parser or prompt the model again, and show why the step ended. I've marked this as a feature request for the maintainers to consider.
Related issues:
[Assistant tool call]format