Spurious "tool call was malformed and could not be parsed" appended after successful tool calls
Summary
In a long interactive session, a user-role message "Your tool call was malformed and could not be parsed. Please retry." is intermittently appended immediately after a tool call — even though that tool call itself executed successfully and returned a normal result. It looks like a spurious/duplicate parse of the assistant turn, not a real failed call.
Environment
- Claude Code:
2.1.158 - Platform: win32 (Windows 11 Pro 10.0.26200)
- Shell: PowerShell 7
- Model: Opus 4.8 (1M context) —
claude-opus-4-8[1m] - Session id:
631092ba-4bd8-464e-a409-62d6742909a5
Observations
- Occurred ~7 times across one session.
- Followed both
ReadandEditcalls. In every case the actual tool call succeeded (content returned / "file has been updated successfully"); the malformed notice was an extra message appended after the successful result. - Not tied to parallel/batched calls. I first suspected batching (multiple
tool_useblocks in one assistant message), but it reproduced on single tool calls too (e.g. a lone successfulEdit), ruling that out. - No stable trigger: assistant turns of the same shape (prose + one tool call) sometimes produced it, sometimes not — it reads as intermittent.
Hypothesis (from the model's vantage point — I can't see the underlying wire format)
The tool-call parser seems to detect a second, incomplete tool-call fragment in the assistant turn besides the one that legitimately executed, and emits the retry notice for that phantom fragment. Possible contributors in the offending turns: large Edit new_string payloads containing triple-backtick fenced code blocks, box-drawing characters (│ ▼ ─ ►), or code-like tokens (e.g. export const ssr = false) interleaved with prose. Since it isn't deterministic, it may instead be a flaky parse/streaming artifact.
Impact
- Non-blocking: real tool calls all succeed; task correctness unaffected.
- Noise: pollutes the transcript, injects spurious "Please retry" user-role turns, and misleads diagnosis (I initially mis-attributed it to batching until single-call reproduction corrected me).
What would help
If the harness logs the raw assistant payload per turn, correlating the "malformed" emissions in this session against the exact bytes sent should reveal whether a stray/partial tool_use block is being parsed. Session id above.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗