Opus 4.8 (1M context) — frequent "tool_use malformed" client errors despite tools executing successfully
Environment
- Model:
claude-opus-4-8-1m(switched toclaude-opus-4-7-1mas workaround mid-session — see below) - Claude Code version: 2.1.92
- Session type: forked from a prior session (this is a variable I could not isolate solo — see Repro)
- OS: Windows 11 + Git Bash
- Workflow: long CI-debugging session with many tool calls (Bash, Edit, Read, WebFetch, subagents)
Symptom
Roughly 5 out of ~15 tool calls on Opus 4.8 fail with:
Your tool call was malformed and could not be parsed. Please retry.
The assistant turn appears empty to the user, and a UserPromptSubmit-style retry prompt arrives next turn. However, the tool actually executed on the server side — verified independently each time:
Edit: subsequentgit diffconfirms the file was modified exactly as intendedBash(gh pr create): the PR was actually created on GitHub (visible at the returned URL)- Subagent (
Agenttool): subagent ran to completion and the structured result was retained in the next assistant turn's context
So the tool call reached the server, ran, and produced correct output — only the client-side parse / surfacing of the assistant message that contained the tool call failed.
Repro / variable isolation
After ~5 occurrences across an hour on Opus 4.8, I switched the same session to Opus 4.7 (1M) via /model. 0 occurrences across 6+ subsequent tool calls in the same session, same workflow, same kinds of tools (Bash, Read, Edit, gh CLI). Strong signal that the regression is model-side rather than environmental.
The one variable I could not isolate solo: the session was forked from a prior conversation. I don't know whether a fresh 4.8 session (no forked history) reproduces — would appreciate help confirming. Three possible outcomes:
- Fresh 4.8 also reproduces → model-level regression in 4.8
- Only forked 4.8 reproduces → interaction between 4.8 and replayed conversation history
- Neither → close
Hypothesis
Plausibly XML close-tag drift in long / nested <parameter> content — e.g. the model emitting </invoke> where </parameter> was expected, causing the client-side parser to drop or mis-attribute the tool_use block. There is a known mode where long args with mixed content trip this; 4.8 appears to have raised the failure rate noticeably.
Observed triggering tool calls in this session:
Editwith multi-linenew_stringcontaining mixed CJK comments + YAML codeBashwith HEREDOC commit messages (multi-line, CJK + ASCII)WebFetchwith a longerpromptarg- (one occurrence after a system-reminder injection arrived between the user message and my tool call — could be coincidence, flagging in case)
Workaround
Switch to Opus 4.7 (1M context) via /model.
Impact
Each failure costs one round-trip + a context-polluting "retry" prompt, and in a long session it accumulates. Worse, because the tool did execute, a careless user might double-execute side-effectful operations (e.g. re-create a PR, double-commit) if they don't notice the empty turn and just re-issue the request.
Happy to provide
- Session transcript excerpts (contains code from a private repo; can redact)
- Specific timestamps / turn boundaries on request
This issue has 6 comments on GitHub. Read the full discussion on GitHub ↗