Repository navigation
Copilot Claude Opus 4.8 emits pseudo tool-call text instead of structured tool calls #31247
Description
Description
With github-copilot/claude-opus-4.8, OpenCode can persist pseudo tool-call text as normal assistant text instead of receiving a structured tool call.
The malformed assistant message can look structurally like this:
role = assistantproviderID = github-copilotmodelID = claude-opus-4.8finish = tool-calls- structured tool parts:
0 - assistant text contains pseudo tool-call markup such as
<invoke ...>or shortcall <tool>lines
This appears to be the root cause behind the assistant-prefill 400 tracked in #31807. After such a malformed finish=tool-calls turn, OpenCode continues the tool loop, but the conversation history effectively ends with an assistant message. Copilot Claude Opus 4.8 then rejects the follow-up request.
Steps to Reproduce
I do not yet have a small deterministic repro, but the issue occurred in real OpenCode TUI sessions with a tool-heavy workflow:
- Start an OpenCode TUI session with
github-copilot/claude-opus-4.8. - Perform a long multi-step task with many tool calls (
read,write,edit,grep,bash, etc.). - Continue the same session through many tool-call turns.
- Inspect local SQLite
message/partmetadata. - Observe assistant text parts containing pseudo tool-call text such as
<invoke ...>orcall read, while the assistant message hasfinish=tool-callsbut no structured tool part.
Expected Behavior
- If the model requests a tool, OpenCode should receive or recover a structured tool call.
- Pseudo tool-call text should not be persisted as normal assistant prose.
- A response with
finish=tool-callsshould not leave OpenCode with zero actual tool parts and then continue the tool loop blindly.
Actual Behavior
In the affected session, Opus 4.8 produced malformed assistant turns where pseudo tool-call text was persisted as normal assistant text parts.
Same-session structural comparison:
| Model | Assistant messages | <invoke> text parts |
call ... text parts |
finish=tool-calls with 0 tool parts |
assistant-prefill API errors |
|---|---|---|---|---|---|
claude-opus-4.6 |
161 | 0 | 0 | 0 | 0 |
claude-opus-4.7 |
71 | 0 | 0 | 0 | 0 |
claude-opus-4.8 |
337 | 13 | 229 | 6 | 6 |
Representative malformed turn shape:
model: github-copilot/claude-opus-4.8
role: assistant
finish: tool-calls
structured tool parts: 0
assistant text contains: <invoke ...>
Every sampled assistant-prefill 400 in #31807 was immediately preceded by this malformed shape.
Additional Evidence
Sanitized DB-derived metadata only:
https://gist.github.com/doomsday616/d3fb56acd0f14964a9797df35f1fcd96
The gist contains only structural metadata from local SQLite message / part rows. Private message text, local paths, usernames, WeChat identifiers, and conversation content are not included.
OpenCode Version
1.17.7
Operating System
Windows 11
Terminal
Windows Terminal / PowerShell 7
Provider / Model
github-copilot / claude-opus-4.8
I tested the same affected session metadata against other Copilot Claude models. In that session, claude-opus-4.6 and claude-opus-4.7 did not show the same malformed pseudo tool-call pattern.
Related Issues
- Copilot Claude Opus 4.8 assistant prefill 400 after malformed pseudo tool-call text #31807 — downstream assistant-prefill 400 after the malformed pseudo tool-call turn leaves the next request ending with assistant.
- gpt-5.3-codex intermittently leaks malformed tool-call text and stops mid-run #15164 — similar class: malformed tool-call text leaks into visible output.
- Interrupted streamed apply_patch call leaves orphaned tool state and leaks internal preparation text #30653 — related interrupted/orphaned tool state and leaked internal preparation text.
- Truncated tool calls are misclassified and unrecoverable (finishReason: length + repairToolCall + doom loop) #18108 — related malformed/truncated tool-call recovery area.
Sanitization
The original full session contains private content. The linked gist only includes sanitized structural metadata needed for debugging.
Activity
github-actions commentedon Jun 7, 2026
This issue does not fully meet our contributing guidelines.
What needs to be fixed:
Please edit this issue to address the above within 2 hours, or it will be automatically closed.
This issue might be a duplicate of existing issues. Please check:
If you believe this was flagged incorrectly, please let a maintainer know.
github-actions commentedon Jun 7, 2026
Thank you for updating the issue with the full report! It now meets our contributing guidelines. The
needs:compliancelabel has been removed.rekram1-node commentedon Jun 7, 2026
can u sed the session this happened in?
opencode export > session.jsonrekram1-node commentedon Jun 8, 2026
I need at least some info from the session just manually sanitize it if ur super concerned
[-]Opus 4.8 via GitHub Copilot leaks repeated literal tool-call text and then hits assistant prefill 400[/-][+]Opus 4.8 via GitHub Copilot leaks repeated literal tool-call text into assistant messages[/+][-]Opus 4.8 via GitHub Copilot leaks repeated literal tool-call text into assistant messages[/-][+]Copilot Claude Opus 4.8 emits pseudo tool-call text instead of structured tool calls[/+]lazyalex616 commentedon Jun 16, 2026
@rekram1-node @simonklee @malventano @marcusquinn I re-checked the local SQLite metadata on OpenCode 1.17.7 and updated this issue plus the sanitized gist.
New finding: this looks like the root cause for the Opus 4.8 failure chain, not just a visible-text leak.
In the affected session,
github-copilot/claude-opus-4.8sometimes produced assistant messages with:finish = tool-calls<invoke ...>or shortcall <tool>linesSame-session comparison:
<invoke>text partscall ...text partsfinish=tool-callswith 0 tool partsclaude-opus-4.6claude-opus-4.7claude-opus-4.8So #31807 appears downstream: after one of these malformed
finish=tool-callsturns, OpenCode continues the loop and the next Copilot Claude request effectively ends with assistant, which triggers the assistant-prefill 400.Updated sanitized evidence:
https://gist.github.com/doomsday616/d3fb56acd0f14964a9797df35f1fcd96
I also withdrew the earlier workaround PR because the better fix should handle the malformed
finish=tool-calls/ no-tool-part response at the root.lazyalex616 commentedon Jun 21, 2026
@thdxr @rekram1-node @kitlangton @simonklee @malventano @marcusquinn @wgu9 @jquense @Nomadcxx @keefetang
Small update after checking the v1.17.9 release: this still does not appear to be fixed in v1.17.9.
This Opus 4.8 pseudo tool-call corruption has been confirmed in v1.17.7 and remains unresolved through v1.17.9. It seriously affects tool-heavy OpenCode usage because malformed
finish=tool-callsturns can poison the session, persist fake tool-call text as assistant text, and then lead to downstream request failures.Please, could someone familiar with provider/tool-call handling take a look? 🙏
。゚(゚´ω`゚)゚。 please have mercy and take a look, we are begging on our paws 🐾
kcz358 commentedon Jun 25, 2026
I have also observed this behavior for copilot opus 4.8 model in opencode. The model keep emits a 'call' token repeatedly even in successful tool calls and eventually failed for calling tools or only emits this
calltoken in response. May I ask are there any updates for this?Nomadcxx commentedon Jun 25, 2026
I'll try take a look at this on the weekend since I still have copilot and can probably re-create.
Nomadcxx commentedon Jun 26, 2026
I opened a fix PR: #34039
copilot opus can say it wants to use a tool without sending opencode an actual tool request. opencode then continues the session as if a tool request exists, and the next copilot request can fail with the assistant-prefill error.
The fix stops that loop. opencode now marks that turn as an error instead of asking copilot again. Normal tool use is unchanged, and the PR includes a regression test for this case.
github-actions commentedon Aug 26, 2026
To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.