[Bug] Anthropic API Error: Model's tool call could not be parsed (retry also failed)

Open 💬 63 comments Opened May 25, 2026 by taira-s0422

Bug Description
claude code opus 4.7がThe model's tool call could not be parsed (retry also failed).という表示で処理が止まってしまうケースが私の環境で多発しています 

Environment Info

  • Platform: darwin
  • Terminal: vscode
  • Version: 2.1.150
  • Feedback ID: 9ac0473c-acb2-4eb0-a61f-4d2bcf6ff26c

Errors

[]

View original on GitHub ↗

63 Comments

github-actions[bot] · 1 month ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/60033
  2. https://github.com/anthropics/claude-code/issues/49747
  3. https://github.com/anthropics/claude-code/issues/48679

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

fancyboi999 · 1 month ago

Same thing here on Opus 4.7 (darwin, CLI). Dug through my local ~/.claude/projects/*.jsonl to see how bad it actually is.

522 sessions total. 12 of them hit this, and every single one is from the last two days (May 25–26) — zero before that. So it reads like a recent regression, not something that's always been around. Across those sessions there were 53 "malformed, please retry" prompts, 23 of which ended in the terminal "retry also failed".

What the failing turns look like in the jsonl: stop_reason comes back as tool_use, but the content is just an empty thinking block (length 0) with no tool_use block at all. The retry returns the same broken shape, so it gives up. One of my turns burned ~18 minutes looping through retries before it died.

Every failing turn is on claude-opus-4-7. Haiku subagent turns in the same sessions never hit it. Feels server-side — context fill and MCP count don't seem to correlate.

A couple of real request IDs from the empty-thinking failures, if anyone wants to trace them server-side:

  • req_011CbQyzAUwitoF7eptKA77v (2026-05-26T09:58:36Z)
  • req_011CbQz1M9vTr2A5VSn6dMTw (2026-05-26T09:58:51Z)

One session alone had 19 of these empty-thinking + stop_reason=tool_use turns.

labuladong · 1 month ago

This issue makes claude code unusable...

Quick workaround:

/model claude-opus-4-6[1m]
catlixin61 · 1 month ago

⏺ The model's tool call could not be parsed (retry also failed). me too

nevermore31 · 1 month ago

me too ! also return me "The model's tool call could not be parsed" , i dont konw how to fix it 2.1.52 also have this bug

RollandXD · 1 month ago

same

minamihiroto · 1 month ago

+1, same issue on Windows 11 with Opus 4.7 — "tool call could not be parsed (retry also failed)" happens frequently and halts the task.

binlee1990 · 1 month ago

same

tooilxui · 1 month ago

same

maxzyma · 1 month ago

+1 on Opus 4.7 (Claude Code CLI, darwin, v2.1.150).

After the parse-failed retry, the next turn often renders just a fragment of text — literally the word "call" — right before the tool-use line. Looks like the start of the function-call token leaking out as plain text when the tool_use block comes back empty. Matches fancyboi999's "empty thinking + stop_reason=tool_use" forensic.

Opus 4.7 only. Haiku subagents in the same session never hit it. Sonnet 4.6 on the same task doesn't reproduce.

hzpkk520 · 1 month ago

<img width="538" height="72" alt="Image" src="https://github.com/user-attachments/assets/ad3461fd-9b05-4704-bda8-1c2302f4129c" />

My system is Ubuntu 24.04.3 LTS (GNU/Linux 6.14.0-1018-aws aarch64).

Same problem. After a very simple question, it kept thinking for about 28mins and returned "The model's tool call could not be parsed (retry also failed)." . It has been like this since 10 hours ago. I've tried so many different ways to solve this, but it was still the same. It could be a potential bug.

AndyShiu · 1 month ago

Data point (model version): In a long coding session with many Edit/Bash tool calls, I repeatedly hit The model's tool call could not be parsed (retry also failed) — the assistant produced empty turns where a tool call should be.

The key finding in my case: it happened consistently on Opus 4.8, and switching to Opus 4.7 (/model claude-opus-4-7) made it stop — the exact same workflow then ran with no parse failures. So 4.8 appears noticeably more prone to this than 4.7 here.

Environment: Claude Code 2.1.154 · darwin/arm64 (macOS 26.4.1) · CLI.

yurukusa · 1 month ago

I've been tracking this cluster for the past two weeks across five filings (#62123, #62344, #62467, #62700, #49747) and the pattern has four distinct sub-shapes, each with a different recovery. The reason /clear works for some reports and not others is that these are four root causes presenting as one surface symptom.
Sub-pattern map:

  • 12A — Long-session few-shot poisoning (#62344): Errors accumulate as the session grows. Past malformed-recovery attempts pollute the recent-tool-call context, biasing subsequent tool calls toward the same malformed shape. Recovery: /clear. The 28-minute thinking case @hzpkk520 reports above looks like this pattern (long session, model thrashing on a poisoned context).
  • 12B — Extended-thinking serialization defect (#62467): The tool call generated inside a thinking block becomes inconsistent at the serialization boundary. Surfaces specifically with reasoning effort enabled. Recovery: turn off extended thinking, or switch model temporarily. /clear does not help because the defect re-occurs on the next thinking-enabled turn.
  • 12C — Spurious "parse failed" notice on a successful call (#62700): The tool call actually executed correctly, but the notice fires anyway. The fragment-of-"call" leakage @maxzyma describes above is a candidate for this — the runtime shows artifact output even though the tool dispatched. Recovery: check the actual tool output before retrying. Both /clear and model switch make it worse by burning context.
  • 12D — Legacy XML format mix in tool arguments (#49747): Specific to long tool-call inputs. The legacy XML closing tag leaks into the new format and trips the parser. Recovery: shorten arguments, split one long call into multiple shorter ones, reduce argument verbosity. /clear does not help because the same long input will reproduce.

The reason a single recovery doesn't work across reports is that 12A's /clear fix actively burns useful context for the 12C and 12D cases.
Identification path (for the case you're seeing right now):

  1. Did the same simple prompt that worked yesterday now fail? → likely 12A (something accumulated in the session).
  2. Do you have extended thinking on? Turn it off briefly. If the failure stops → 12B.
  3. Check the tool output area for actual content beneath the notice. If something is there → likely 12C.
  4. Was the failing call long-argument or many-argument? → check 12D.

Operator-side advisory hooks (free, MIT): I shipped four PostToolUse / PreToolUse advisory hooks in cc-safe-setup over the past 36 hours that detect each sub-pattern at the boundary and surface the matching recovery hint — never blocking, just observation + advice on the right recovery so misapplied /clear doesn't waste context. The list is in the cluster-12 field guide Gist (Section 5 has the install commands). PRs yurukusa/cc-safe-setup#406 / #419 / #423 / #424 if you prefer reading the source.
The four hooks together cover all four sub-patterns at the advisory level — the durable fix is upstream (the model attention layer for 12A/12B, the harness parser for 12C, the serialization boundary for 12D), but knowing which sub-pattern is hitting you means you can apply the correct one of four different recoveries rather than guessing.

ynatz · 1 month ago

This issue also occurs in Opus 4.8. Since it stops frequently and is unusable, I'm making do with claude-opus-4-6[1m] for now.

In Opus 4.8 and 4.7, where this issue occurs frequently, it’s not just a matter of the "Dynamic workflows" feature, the software is rendered unusable not only for long-term parallel processing but even for everyday tasks.
To be honest, it’s completely useless.

https://claude.com/blog/introducing-dynamic-workflows-in-claude-code

  • Windows 11 Pro + WSL (Ubuntu 24.04 LTS)
  • Claude Code 2.1.156
  • Claude Opus 4.8
fansen · 1 month ago

Data point — version gradient (4.6 clean → 4.7 onset → 4.8 worst)

Adding a longitudinal data point that lines up with @AndyShiu and the empty-thinking forensics above.

  • Opus 4.6 (including the 1M-context variant): never hit this, across heavy daily use. This rules out the 1M context window itself as the trigger.
  • Opus 4.7: this is where it started for me — consistent with the 2026-05-20 internal-signature switch documented in #61133.
  • Opus 4.8 [1m]: worst so far — frequent enough to make the CLI effectively unusable for ~a week.

So the trigger tracks the model generation (4.7+), not the 1M context window, and not user config.

Shape of the failing turns (matches @fancyboi999 / @maxzyma):

  • stop_reason comes back as a tool-use turn, but the body has no tool_use block — only thinking/text. The retry returns the identical broken shape, hence "retry also failed".
  • Failures land after long single turns (2–4 min) and consistently on local Write/Edit calls writing escape-dense (CJK) content — never on an MCP tool call in my logs. This looks like it may be the same mechanism as #60033 (large escape-dense content → malformed tool-input JSON → identical retry).

Ruled out locally (so others can skip these):

  • Not context size — my largest sessions (1400+ messages) had zero failures, while short sessions hit it.
  • Not a third-party proxy (official endpoint), not a single Claude Code version (spans 2.1.145 → 2.1.156), not MCP tool-set size.
  • Correlates with high effort (the internal signature in #61133 literally contains high), but downgrading effort is a self-defeating workaround, not a fix.

Environment: Claude Code 2.1.156 · macOS (darwin/arm64) · CLI · Opus 4.8 [1m].

Only workaround that doesn't cripple the model: /model back to 4.6 (or 4.7 per @AndyShiu). Which means the newest model is, in practice, unusable for tool-heavy work right now. Would really appreciate this getting prioritized rather than auto-closed as a dup — the version gradient here is a concrete lead.

yurukusa · 1 month ago

@fansen — the version gradient (4.6 clean → 4.7 onset → 4.8 worst) is the cleanest longitudinal pin this cluster has so far, and pairing it with @AndyShiu's reverse repro (4.8 fail → 4.7 clean for the same workflow) and @maxzyma's "literally the word 'call' leaking out as plain text" forensic gives us a three-data-point picture pinning the trigger to the model generation rather than to a transient harness state.

This matters for operator-side decisions because the workaround landscape splits cleanly:

  1. Operators on 4.8 with the parse failures: per AndyShiu's repro, downgrading the model via /model claude-opus-4-7 is the fast unblock. The trade-off is the 4.8 capability you're giving up, which is significant on harder reasoning tasks but tolerable for most code-editing workflows. ynatz's data point (4.6[1m] as the fallback when even 4.7 fails) extends the same logic — operators picking durability over capability are walking back the model generation, not forward.
  1. Operators who need 4.8's capability: the cc-safe-setup advisory hooks I documented for the four Cluster 12 sub-patterns (cluster-tracker entry) are the next-best thing. They don't prevent the parse failure, but they tell you which of the four sub-patterns (12A in-context poisoning, 12B extended-thinking serialization, 12C spurious malformed notice, 12D legacy XML format mix) you're seeing on a given session, so the recovery (which differs per sub-pattern — /clear works for 12A but not 12B/12C/12D) is the right one rather than a guessed one.

Your "internal-signature switch documented in #61133" pointer is the part I want to follow up on. If the 2026-05-20 switch is what introduced the regression at the 4.7 generation and 4.8 carries the same surface forward, that's a structural anchor for the upstream fix discussion that the Cluster 12 documentation needs and currently doesn't have. I'll dig into #61133 and integrate the signature-switch framing into the cluster-tracker entry's "upstream status" section so future operators arriving at the cluster framing get the model-generation anchor without having to reconstruct it from the comments thread here.

Adding a fourth longitudinal data point would help further pin the regression: are there reports of 4.6 sessions that resumed under 4.7 or 4.8 triggering the parse failure on the continuation, even though the same conversation history was clean under 4.6? If yes, that would distinguish "the model generation produces malformed tool calls" from "the model generation mis-parses inputs that were fine under a prior generation," which is a different upstream fix surface.

catch6 · 1 month ago

+1

tzupingchenwork · 1 month ago

same

wqq-java · 1 month ago

The model's tool call could not be parsed (retry also failed). me too

chengv · 1 month ago

me too

Chaoqi31 · 1 month ago

same on mac with Opus 4.8

Kendrick-Song · 1 month ago

⏺ The model's tool call could not be parsed (retry also failed). me too

opencaw · 1 month ago

+1

kyosora · 1 month ago

me too

yurukusa · 1 month ago

Follow-up: #61133 integration and the model-generation anchor
I dug into #61133 as I said I would. The signature-switch evidence is the cleanest upstream anchor this cluster has, and it explains the 4.7/4.8 gradient that @AndyShiu, @ynatz, and @fansen documented above. Sharing the integration in case it's useful for triage.
What #61133 shows (full decode, not sampled):
| Date | Opus 4.7 signature model-name | retry also failed events |
|---|---|---|
| 05-19 | claude-opus-4-7 (174/174) | 0 |
| 05-20 | claude-opus-4-7 (8) + claude-quoll-v7-hr-fast-ab-high-p (45) | 0 |
| 05-21 | claude-quoll-v7-hr-fast-ab-high-p (491/491) | 29 |
This is the per-day breakdown of the protobuf model-name field decoded from the thinking block signature. The regression onset (2026-05-21) coincides exactly with the day Opus 4.7 responses fully transitioned to the claude-quoll-v7-hr-fast-ab-high-p internal signature. Every malformed response in @vipo's transcript DB decodes to that signature; none of the claude-opus-4-7 signature responses (through 05-19) produced a failure.
Why this matters for the 4.7 → 4.8 gradient @fansen and @AndyShiu reported:
The pattern reads as the same internal-signature regression carried forward through the model generation. The reverse-repro (@AndyShiu: 4.8 fail → 4.7 clean for the same workflow) and the longitudinal data (@fansen: 4.6 clean → 4.7 onset → 4.8 worst, including 1M context) both point to model-generation as the trigger rather than client config, harness version, or context size. The 2026-05-20 signature switch is the structural anchor that ties the surface symptom ("retry also failed") to a date-precise internal change.
This refines the operator-side decision matrix:

  • Downgrade to claude-opus-4-6[1m] — the option @labuladong, @ynatz, and @fansen converged on. Trade-off is the 4.7/4.8 capability you're walking away from, but per @fansen's data this is the only model generation with zero retry also failed events in their dataset (4.6 clean across heavy daily use).
  • Downgrade to claude-opus-4-7 — per @AndyShiu, sufficient if you're hitting it on 4.8 and want to stay one generation back. Won't help if your reports were on 4.7 already (the signature is the same).
  • Stay on the affected generation + operator-side detection — knowing which of the four Cluster 12 sub-patterns (12A in-context poisoning, 12B extended-thinking serialization, 12C spurious malformed notice, 12D legacy XML mix) you're hitting tells you which recovery to apply, since the recoveries differ per sub-pattern. The four advisory hooks I mentioned previously (cc-safe-setup PRs #406 / #419 / #423 / #424) detect each sub-pattern at the tool-call boundary.

The fourth data point I asked about above:
@vipo, if you have access to it — does a 4.6 session resumed under 4.7 (signature claude-quoll-v7-hr-fast-ab-high-p) reproduce the parse failure on the continuation, even though the same conversation history was clean under 4.6? If yes, the fix surface is "the new signature mis-parses inputs that the prior signature handled correctly," which is a different upstream surface from "the new signature generates malformed tool calls." Either is consistent with the surface symptom; they have different fix paths. The transcript DB you have would let this be checked with the same decode method.
I'll update the Cluster 12 tracker entry to anchor the upstream-status section to the 2026-05-20 signature switch so operators arriving at the cluster framing don't have to reconstruct the model-generation anchor from this comment thread. Thanks @fansen / @AndyShiu / @ynatz for the version-gradient data — three independent longitudinal data points was what the cluster needed to move from "intermittent" to "regression with a date."

bb774-cyber · 1 month ago

Additional data: malformed tool call reproduced on Windows / Opus 4.8 / Claude Desktop

Same error signature ("Your tool call was malformed and could not be parsed. Please retry.")
on a different environment than the original report:

| | Original | This report |
|---------|-------------|-----------------|
| OS | macOS | Windows |
| Model | Opus 4.7 | Opus 4.8 |
| Host | VS Code ext | Claude Desktop |
| Version | 2.1.150 | 2.1.156 |

OS, model, and host all differ yet the error is identical → likely neither
macOS- nor VS Code-specific.

Core finding

18 parse errors across 8 Opus sessions (117 local logs analyzed). All 18 share one
signature: the assistant turn had stop_reason=tool_use, but no parseable tool_use
block.

  • 16/18 — stop_reason=tool_use, yet no tool_use block in the recorded content (only

thinking/text): the model signalled "calling a tool" but emitted no parseable block.

  • 2/18 — a tool_use block leaked into a text block as raw invocation XML, prefixed

with the literal token court:

court
<invoke name="mcp__Claude_in_Chrome__tabs_context_mcp">
<parameter name="createIfEmpty">true</parameter>
</invoke>

The "court leak" is the minority shape (2/18, both on MCP tools); the dominant failure
is stop_reason=tool_use with the tool_use block missing/unparseable.

Not limited to MCP

Failures also occurred on built-in tools (Write, Edit, Grep, PowerShell), not only
Claude-in-Chrome MCP calls — including live reproductions during ordinary tool use.

Environment / behavior

  • Settings: CLAUDE_CODE_EFFORT_LEVEL=max, model opus[1m].
  • Sometimes recovers on retry; consecutive failures reach the original "retry also failed".
trylovetom · 1 month ago

Same here, and I downgrade the model from opus-4.8 to opus-4.6 everything is working fine.

ynatz · 1 month ago

I keep seeing claims on X and the official blog saying, "Opus 4.8 lets you run longer tasks!" but which Opus are they referring to?

The one available to us has had frequent errors that prevent even basic tool calls from completing for over 10 days straight, across both 4.7 and 4.8, with no acknowledgment on the status page. Yet official announcements keep touting how great Opus 4.8 is.

yelban · 1 month ago

Data point: Opus 4.6 as Dynamic Workflow workaround

Adding a practical workaround that goes beyond just "downgrade to avoid the error."

Environment: macOS, CLI, v2.1.158

The version gradient holds: Confirming what @fansen, @AndyShiu, and @ynatz documented — Opus 4.6 (including claude-opus-4-6[1m]) has been completely clean across heavy daily use. 4.7 intermittent, 4.8 worst.

Why this matters beyond the parse error: Opus 4.6 is currently the only version that can reliably run Dynamic Workflows. I tested this with a real workload — 35 files, each requiring multiple tool calls (Read 3-5 files, analyze, Write output), 8 structured sections per report.

What happened on 4.8: Workflows would fail silently. The workflow system reports agents as "completed" even when they hit rate limits or parse errors. I launched 34 agents, got 34/34 completed in 19 seconds — output folder was empty. Every agent died on the tool-call parse error.

What works on 4.6:

/model claude-opus-4-6[1m]

Then batch the workflow — 4 agents per batch to avoid rate limits:

export const meta = {
  name: 'batch-analysis',
  description: 'Batch analysis via args',
  phases: [{ title: 'Analyze', detail: 'One agent per item' }]
}

const ITEMS = args  // pass different batches each invocation

phase('Analyze')
const results = await parallel(ITEMS.map(function(item) {
  return function() {
    return agent(buildPrompt(item), { label: item.name, phase: 'Analyze' })
  }
}))

Invoke with batches of 4:

Workflow({
  scriptPath: "path/to/script.js",
  args: [/* 4 items per batch */]
})

Results: 35 files analyzed in ~45 minutes (9 batches of 4, ~5 min each). All 35 reports verified complete via shell validation.

Key lesson: Always validate workflow output with shell commands. completed: N/N in the workflow result does NOT mean agents successfully finished their work — it just means they stopped running.

Workaround: /model claude-opus-4-6[1m] — no perceptible reasoning downgrade, full workflow stability.

(Side note: I used a small declarative-contract plugin to lock down success criteria before each batch — happy to share if useful, but the core workaround above stands on its own.)

WangDanpeng · 1 month ago

Reproducible debug evidence — 36-byte SSE heartbeat stall pattern

Observed two consecutive occurrences today (2026-05-31) with identical behavior on macOS, CC v2.1.158, model claude-opus-4-8.

Pattern: After receiving a partial response (~4–7 KB), the stream stops producing tokens entirely and switches to emitting exactly +36 bytes every ~45 seconds (SSE keep-alive packets). The connection is maintained until the 300s idle deadline is hit, at which point the stream "completes" with an incomplete response body — stop_reason: tool_use but no tool_use block present, causing the parse error.

| Occurrence | Stall duration | Bytes at stall start | Heartbeat interval |
|---|---|---|---|
| 1 | 241.2s | ~7,023 bytes | +36 bytes / ~45s |
| 2 | 304.8s | ~4,233 bytes | +36 bytes / ~45s |

Request IDs:

  • ade8e09b-a2e2-46e8-8f10-5cf73df8970b
  • 06ed9b3c-f65e-4331-bae5-ff3f36d870ee

Debug log extract (occurrence 1):
[WARN] [Stall] stream_idle_partial lastChunkAgeMs=15000 bytesTotal=7023
[WARN] [Stall] stream_idle_partial lastChunkAgeMs=30000 bytesTotal=7059 (+36)
[WARN] [Stall] stream_idle_partial lastChunkAgeMs=15001 bytesTotal=7095 (+36)
... (repeated for 241s)
[WARN] Streaming stall detected: 241.2s gap between events (stall #1)
[WARN] Streaming completed with 1 stall(s), total stall time: 241.2s

The stall duration is increasing across occurrences (241s → 304s), suggesting server-side resource pressure is worsening. Network is confirmed not a factor — heartbeats arrive with clock-level regularity (~45s ±1s), and retry connections establish in 3–4s.

This issue appears related to #61133 (closed) but persists on claude-opus-4-8 (v2.1.158). The root behavior is identical: server maintains SSE connection via keep-alive while inference is stalled, then closes with an incomplete response.

BrownBear127 · 1 month ago

Reproducing consistently on 2.1.158 + Opus 4.8 (native install, macOS arm64). Adding a layer/root-cause breakdown from dissecting the CLI binary, plus a safety warning I think is under-reported in this thread.

This is model-side, surfaced by the client's streaming assembler — not a client parser bug.

  • Both the user-visible The model's tool call could not be parsed (retry also failed). and the injected retry turn Your tool call was malformed and could not be parsed. Please retry. are string literals in the CLI bundle. So the client is reporting/handling the failure, not producing it.
  • The failure itself: the model returns stop_reason=tool_use but the streamed content carries no valid tool_use block — an empty/early-terminated block, or a stray token replacing the opening markup prefix (see #63879, #63604, #63998). It's exposed by the always-on streaming tool_use assembly that became default in 2.1.154.
  • I installed 2.1.159 (currently the next tag) in isolation and diffed it against 2.1.158: the tool-parse error strings and the SSE delta event names (input_json_delta, content_block_*) are unchanged (0 added / 0 removed); the rest of the 158→159 delta is dominated by re-minification. So 2.1.159 is not a client-side fix for this — consistent with a model-side cause.

⚠️ Safety: the tool often DID execute server-side even though the client shows "could not be parsed."
Before manually retrying, verify the side effects weren't already applied (git log/status, file state, PR list, outbound API calls). Blind retries risk double-commits / duplicate PRs / repeated writes. (Also raised in #63687.)

Frequency — matches the quantification in #63583 (Opus 4.8 ~13.3%, Opus 4.7 ~7.1%, Sonnet 4.6 0%). In one long Opus-4.8 session I counted 45 parse failures: 18 auto-recovered via the injected retry, 27 surfaced as red errors.

Trigger recipe (the more boxes ticked, the higher the rate): Opus 4.8 + 1M context + high/xhigh effort (max extended thinking) + long session / large cache + a dynamic toolset (Skill / MCP / subagents causing tools_changed cache churn).

Mitigations I tested:

  • Lowering /effort to medium/low reduces frequency but doesn't eliminate it (4.8's adaptive thinking can't be fully turned off — #63481).
  • Switching to Opus 4.7 drops it, but #63583 still shows ~7.1%; Sonnet 4.6 is the only 0% option (but it's a model downgrade).
  • Don't --resume a poisoned session — it replays the bad turn. Start fresh; /clear only helps temporarily.
  • Note: on Opus 4.8 you cannot disable 1M context (it's 1M-only), so the older "drop to 200k to avoid the 1M streaming path" workaround is not available on 4.8.

Related: #63875 #63879 #63604 #63481 #63583 #63687 #63998 #64176 (and #61133, the closed Opus-4.7 precursor).

GGGODLIN · 1 month ago

In case it helps anyone else stuck here: the failed turns just pile up at the tail of the session .jsonl, and --resume replays them — so I figured I could just strip that bad tail and resume from the last clean turn.

Wrote a small stdlib-only Python script that does exactly that — it drops the contiguous bad block (the empty-thinking stop_reason: tool_use turns + the retry/synthetic-error lines), rewinds to the last clean leaf (a user message / tool_result / normally-ended assistant turn), backs the file up first, then you --resume. It refuses to touch sessions that aren't poisoned and won't leave a dangling tool_use.

Tried it on my own stuck sessions and it brought them back with all the prior context intact (unlike /clear).

claude-code-unpoison

Caveats: tail-cascade only (mid-conversation poison → /compact is safer), and it edits an unsupported internal file so do a dry-run first. It's a stopgap, not a fix — the durable workaround is still /model claude-opus-4-6[1m] or Sonnet 4.6 for tool-heavy work.

TimJi · 1 month ago

same problem, opus 4.8, xHigh, in worktree

pengchengneo · 1 month ago

same @

ynatz · 1 month ago

The other failure shape: silent stops with no error, present since the 4.7 regression

Almost every forensic in this thread is some flavor of "stop_reason=tool_use but no tool_use block," surfaced as the visible "could not be parsed" notice. There has been a second shape running alongside it the whole time though: turns that just stop silently, with no error and no notice. For me this has been frequent ever since 4.7 broke around 2026-05-20, in step with the parse failures. It gets reported far less because there's no error string to copy-paste, so it tends to read as "the CLI hung" rather than as part of this cluster. I opened the session .jsonl to see what the silent turn looks like inside, and it's the same family as the tool_use cases, just with a different surface.

Environment:

  • Claude Code 2.1.159
  • Ubuntu 24.04 (WSL)
  • Claude Opus 4.8
  • high effort

What it looks like to the user: mid-conversation, an ordinary chat turn (no tools, no file edits) simply stops. No "could not be parsed" notice, no red error, the turn ends producing nothing visible.

Forensics from the session .jsonl, the final assistant turn:

stop_reason: end_turn
model: claude-opus-4-8
content: [ { type: "thinking", length: 193 } ]   <- thinking block has real content
                                                 <- NO text block, NO tool_use block
usage.output_tokens: 423
ts: 2026-06-01T12:48:27.982Z

The model spent 423 output tokens, emitted a non-empty thinking block, then closed the turn with end_turn before generating any user-visible text. From the user side it just goes quiet, which is why this shape is easy to miss in the reports here.

How it differs from the parse-error reports above:

| Reported pattern (this thread) | Silent-stop shape |
|---|---|
| stop_reason = tool_use | stop_reason = end_turn |
| tool_use block missing | text block missing |
| empty thinking (len 0) in some reports | thinking non-empty (len 193) |
| "could not be parsed" shown | no error, silent |
| triggered by a tool call | no tool involved at all |

The closest existing analysis is @yurukusa's 12B (extended-thinking serialization defect), but that's framed around a tool call generated inside the thinking block. In the silent-stop shape there's no tool call anywhere, just thinking, then nothing, then end_turn.

Why I think this matters:

  1. It isn't a tool-parser problem. With zero tools in the turn, the failure can't be in tool_use assembly. The break is one layer earlier: content generation right after a thinking block fails to emit the main body, text in this case, tool_use in the majority of reports. The "malformed/parse" notice is just the most common way it shows, because most heavy turns happen to end in a tool call. When the turn would have ended in plain text instead, you get a silent stop and no notice fires.
  1. It undercuts the "Opus 4.8 is built for long-running tasks" framing. If a plain high-effort chat turn can silently drop its body, the failure isn't gated on tool-heavy workloads, those just hit it far more often by sheer volume. A long-running task is, by definition, a long chain of high-effort thinking/tool boundaries, and it only takes one of them dropping its body to break the run.

Same version gradient others reported holds here, for both shapes: 4.6 (incl. [1m]) clean, 4.7/4.8 not, and the silent stops started for me on the same 05-20 boundary as the parse failures. Back on /model claude-opus-4-6[1m] for anything real.

wqq-java · 1 month ago

The model's tool call could not be parsed (retry also failed). Feedback ID: dbaa81ef-e384-4a42-be79-de5a24da51e6

BukeLy · 1 month ago

I can also reproduce this on claude-opus-4-8. Same error: "The model's tool call could not be parsed (retry also failed)". Switching away from Opus seems to be the only reliable workaround.

cut0 · 1 month ago

"The model's tool call could not be parsed (retry also failed).The model's tool call could not be parsed (retry also failed)."
I'm getting this error on both Opus 4.7 and 4.8.

By the way, I'm a paying Max Plan ($100) subscriber.

qfdk · 1 month ago

Possible workaround: I kept hitting this in Chinese sessions; a new session in
English or French
stopped it for me (~30 min, no recurrence). Seems tied to CJK /
non-ASCII in tool-call arguments — your Japanese report fits. More in #63875.

Env: Claude Code 2.1.160, model claude-opus-4-8[1m], macOS.

18689221165 · 1 month ago

Adding another macOS data point with transcript-level evidence — same thinking-only block + stop_reason=tool_use + zero tool_use blocks signature.

Environment

  • Claude Code CLI 2.1.160
  • Model: claude-opus-4-8[1m]
  • Platform: macOS (Darwin 24.4.0)
  • Session type: mixed Bash/Read/Edit/WebFetch over a long-running engineering session (zh-CN locale, CJK text in prompts)

What I observed

7 occurrences of Your tool call was malformed and could not be parsed. Please retry. in a single session. Cross-checking my ~/.claude/projects/**/<session>.jsonl transcripts shows every failed turn has exactly the same shape:

| field | value |
|---|---|
| model | claude-opus-4-8 |
| stop_reason | tool_use |
| content blocks present | thinking only — no text, no tool_use |
| tool_use block count | 0 |
| output_tokens | 457 / 622 / 794 / 910 / 1031 / 1038 / 1058 / 1196 / 1223 / 1322 / 1644 / 1936 / 2348 / 3867 |

So the model did generate hundreds-to-thousands of output tokens, but the only content block surfacing to the harness is a (signed/redacted) thinking block. The tool_use block is simply missing — fully consistent with the diagnosis from #63481 / #64235 / #64418.

Cross-session sanity check

Same conversation, switched to claude-opus-4-7 via /model. Next 4 assistant turns: every single one contains the proper three-block layout (thinking + text + tool_use), 0 malformed errors. Scanning every transcript across every project under ~/.claude/projects/ confirms all 9 historical occurrences of this error string are localized to the 4.8 turns of this one session; 4.7 across many months of usage: zero.

One small repro note

In my session, two of the 7 failures occurred immediately after a turn where the prior tool result contained ~10 KB of tccli JSON output (Tencent Cloud CLI). The other 5 occurred after relatively small tool results. So at least in my sample, large preceding tool output is not required — it happens on lightweight turns too, matching tsaijamey's Linux short-session counterexample in #64418.

Workaround confirmed: /model claude-opus-4-7 — instant recovery, no other config changes.

Would be very helpful to get any acknowledgement / ETA from Anthropic on this. The aggregated evidence across #62123 / #63481 / #64176 / #64235 / #64418 / #64658 already pins the regression window (2.1.150–2.1.158), the failure shape (stop_reason=tool_use + 0 tool_use blocks), the affected model (claude-opus-4-8), and a clean workaround. 🙏

ace-express · 1 month ago
rambocode · 1 month ago

same for me

bonobozzzz · 1 month ago

same

1690834643 · 1 month ago

Fresh reproduction that corroborates #64955 (non-ASCII tool calls) and #65247 (Opus 4.8 + extended thinking + large cache_read context), with the root cause flagged in #63998 (dropped antml: prefix).

Environment

  • Claude Code CLI; model Opus 4.8 1M context (claude-opus-4-8[1m]); effort = max (extended thinking on)
  • WSL2 Linux; zh-CN session, so assistant output is almost entirely non-ASCII (Chinese)
  • Very large re-injected context (a long planning-doc system-reminder re-sent every turn)

Symptom

  • "tool call could not be parsed (retry also failed)" fired ~15 times in a single session.
  • Key detail: in several cases the tool did execute successfully (files written, bash ran to completion) yet the harness still reported a parse failure and forced a retry, causing duplicate work and hangs.
  • Live-reproduced the #63998 mechanism: emitted calls intermittently lost the antml: prefix (<invoke name="Bash"> instead of the prefixed form), which then cascades into the parse-fail + retry loop.

Correlation: failure rate visibly rises with (a) longer extended-thinking blocks, (b) larger re-injected context, and (c) heavier non-ASCII (Chinese) output — consistent with #64955 and #65247.

yoppyDev · 1 month ago

same

tznthou · 1 month ago

Same here since 2026-05-23. Opus 4.7 → 4.8, both affected. CJK (Traditional Chinese) heavy sessions, long context. Workaround: /model claude-opus-4-6[1m].

okuyam2y · 1 month ago

A parser-resilience angle, from maintaining a text-based tool-call parser (XML/JSON) for a non-function-calling gateway: this is recoverable on the harness side, and the real damage is the history poisoning — not the single malformed call.

Two mitigations that would cover most reports in this cluster:

1. Tolerant parse + normalize. The failures have a small, recognizable set of degraded shapes — antml: prefix dropped (bare <invoke>/<parameter>), a stray short leading token (count/court) before the opening, and occasionally full-width brackets. Scanning for the opening sequence and normalizing these to the canonical form (instead of requiring an exact match at the start of the block) recovers the turn instead of dropping it.

2. Don't let the malformed block re-enter context. The cascade (#62344's "few-shot poisoning", #63998) is the actual blocker: once one broken call lands in the transcript, the model pattern-matches its own prior output and every subsequent call breaks until /clear. On parse failure, persisting the normalized form (or omitting the raw broken block) instead of the raw malformed text breaks the self-reinforcement. The #63998 user-side workaround — emit the tool call as the first tokens with no preamble, don't echo the broken lines — is essentially the harness doing this by hand.

Tolerant parsing fixes the symptom; not feeding the broken output back into context fixes the cascade.

rasshii · 1 month ago

Still reproducing on the latest build — adding quantified data from a heavy-CJK (Japanese) environment.

Environment (exact match to this issue)

  • Platform: darwin (macOS, Darwin 25.5.0), VSCode extension
  • CLI: 2.1.165 (agent wrapper 2-1-167), autoUpdatesChannel: latest
  • Model: claude-opus-4-8, 1M context, effort: xhigh
  • Responses are in Japanese (long-form CJK); extended thinking always on

Quantified frequency (from local transcripts)
Counting only the client-injected retry marker (type=user, isMeta=true, content == "Your tool call was malformed and could not be parsed. Please retry.") to exclude any discussion/quote mentions:

  • 232 real parse-failure events across 59 sessions, over 2026-05-14 → 2026-06-07.
  • 222 of them are after the Opus 4.8 rollout (2026-05-28); the remaining 10 were on Opus 4.7 (2026-05-14–15).
  • Daily concentration after the rollout:
  • 2026-05-29: 52
  • 2026-05-30: 22
  • 2026-06-04: 37
  • 2026-06-05: 79
  • 2026-06-07: still reproducing on 2.1.165 (latest)

Signature (consistent with #63998 / #49747)
stop_reason=tool_use but the tool_use block is missing or malformed; a stray lowercase token (observed drift in my sessions: countcoursecallcourt) is prepended on the line immediately before the tool-call XML, and/or the antml: namespace prefix is dropped from invoke/parameter tags (per #63998's analysis). The "(retry also failed)" text appears to be a client-synthesized fallback after the internal retry also returns a malformed block.

Aggravating factors (reported across #49747 / #62123 / #65247 and/or observed locally): long-form CJK tool arguments, extended/interleaved thinking, large cache_read on long sessions, effort=xhigh, and parallel tool calls. This environment hits all of them simultaneously, which may explain the above-baseline rate.

Happy to provide anonymized transcript excerpts or a Feedback ID if that helps triage. Confirming this is not fixed as of 2.1.165 — no changelog entry for tool-call parsing through 2.1.168.

yurukusa · 1 month ago

This is a real, widespread, version-sensitive CLI parse regression — not a problem with your prompts or escaping. It fires even on trivial calls (a 68-char Read whose entire input is a single file_path, per #66247), and the CLI's own wording ("malformed and could not be parsed … retry also failed") shows it failing while accumulating the streamed tool_use JSON and then losing the turn.

The failure rate clearly tracks the CLI version — but which version is worst differs by environment, so don't blindly downgrade to whatever someone else recommends. #66247 measured an ~8× jump at 2.1.165 (1.85‰ → 16.4‰). On my own logs the rates are much lower overall and peak on different versions (2.1.153 and 2.1.168), with 2.1.162/163/165 near zero. So the reliable move is to measure your own rate per version and pin to a low one.

Self-check (read-only, runs over your local logs — sends nothing):

python3 - <<'PY'
import json, glob, os, collections
tot, fail = collections.Counter(), collections.Counter()
for f in glob.glob(os.path.expanduser("~/.claude/projects/*/*.jsonl")):
    for line in open(f, encoding="utf-8", errors="replace"):
        try: o = json.loads(line)
        except: continue
        v = o.get("version")
        if not v: continue
        tot[v] += 1
        if "malformed and could not be parsed" in line: fail[v] += 1
print("version    msgs   fails   per-mille")
for v in sorted(tot):
    if tot[v] < 200: continue
    print(f"{v:10s} {tot[v]:6d} {fail[v]:6d}   {fail[v]/tot[v]*1000:6.2f}")
PY

Pin to whichever recent version shows the lowest rate for you (npm i -g @anthropic-ai/claude-code@<version>), then re-measure after a day.

When it does hit: the turn is lost, but everything before it is already written to the transcript — just resume the session and re-issue the last instruction; the prior work isn't gone. Lowering reasoning effort also appears to reduce the hit rate for some people (fewer/longer tool-call streams to mis-parse), though that part is anecdotal.

(The method and the 8× baseline come from #66247, which has the fuller per-version breakdown.)

odakin · 1 month ago

Corroborating this on Claude Code CLI 2.1.165.

Environment:

  • Model: Opus 4.8, 1M-context session
  • OS: macOS
  • Workload: heavy non-ASCII (Japanese) tool-call bodies/arguments

Repro signal:

  • Strongly correlated with (a) parallel tool calls in a single turn and

(b) non-ASCII-heavy tool calls. Forcing one tool call per turn reduces
the frequency dramatically (it does not eliminate it).

  • Persists across fresh sessions and after changing prompt/formatting

style, which points to model-side tool_use serialization rather than
anything in the prompt text.

  • Once a malformed tool call lands in the context, automatic retries tend

to keep failing (looks like few-shot poisoning); starting a fresh session
is the only reliable recovery.

Net effect: stalls the session (no destructive action — the tool just
doesn't execute), but it repeatedly interrupts long working sessions.

Also consistent with the more specific reports in #64684 (antml: prefix
dropped in long Opus 4.8 1M-context sessions) and #66247 (~8x jump since
CLI 2.1.165).

odakin · 1 month ago

Another occurrence on claude-opus-4-8[1m] (Opus 4.8, 1M-context variant), macOS — adding as a frequency/profile data point for the cluster being cross-referenced in this thread.

  • Trigger profile: corrupted mid-session during heavy non-ASCII editing (Japanese prose + LaTeX/math symbols) with several file edits in the same turn. Consistent with the non-ASCII / parallel-tool-call sub-shape called out in #64955 and #64235.
  • Retry: re-sends re-emit the identical corrupted tool call and fail at the same point; only a fresh session recovered it (matches other reports here).
  • Recovery: nothing was actually lost — the in-flight work was already written to disk as uncommitted changes, so a fresh session could verify and commit the working tree directly, with no transcript replay needed. A useful mitigation when the work product is files on disk rather than chat state (complements the unpoison-tail script posted in #64235).
ynatz · 1 month ago

The third failure shape: Opus 4.8 hallucinates entire conversations and fabricates tool results

Following up on my previous comments (the parse-error shape in comments 1 and 2, and the silent-stop shape in comment 3). I periodically test whether 4.7/4.8 have been fixed. Today (June 9) I ran two sessions on Opus 4.8, and both exhibited a third, strictly worse failure mode.

Instead of stopping with a parse error or going silent, the model continues running on fabricated context, hallucinating tool results, user messages, and multi-turn dialogues that never happened.

Session 1: Hallucinated an entire multi-turn conversation inside extended thinking
  • Triggered by a simple task: fetch a GitLab issue and save it as a spec file
  • The task completed successfully (file was saved correctly)
  • After receiving the final Read result, the model entered ~6 minutes of extended thinking
  • Inside that thinking block, it hallucinated:
  • Additional tool calls (grep, Read, wc) and their fabricated results
  • Multiple turns of user dialogue that never happened
  • The user accusing it of "fabrication" and demanding an explanation
  • A verification process where the user ran cat -n to cross-check
  • The model then output a lengthy apology and self-defense, responding to accusations that were never made
  • Verification: I analyzed the session JSONL and confirmed via UUID chain that no user message exists between the Read tool_result and the thinking block. The user said nothing after the initial command.
Session 2: Fabricated tool results while tools were actually being called
  • Triggered by an code review task
  • Tools were invoked and real tool_result entries exist in the log
  • However, the model's interpretation of the results diverged from reality
  • It claimed "grep output is severely corrupted" and "serious tool output contamination"
  • Without any user challenge, it then volunteered: "I was writing tool results myself without actually calling the tools"
  • It cycled through deflection ("tool output contamination") and self-correction on its own. The user only observed and eventually aborted the session.
Key observations
  • Both occurred early in the session (within the first few tool calls), not a long-context degradation issue
  • Opus 4.6 works flawlessly on the same tasks in the same environment
  • The hallucinations are highly coherent and specific (fabricated git hashes, concrete error messages, plausible dialogue), making them nearly impossible to detect without log-level verification
The progression across all three shapes

| Shape | Model | Behavior | Detectability |
|---|---|---|---|
| Parse error (this thread's main report) | 4.7 / 4.8 | Malformed tool_use, "could not be parsed" | Visible: error shown |
| Silent stop ([my previous comment](#issuecomment-4592929121)) | 4.7 / 4.8 | Thinking emitted, text/tool_use body dropped, end_turn | Invisible: no error, just silence |
| Hallucination (this comment) | 4.8 | Plausible tool results or entire conversations fabricated in thinking, then acted upon | Actively deceptive: looks like normal operation |

Each shape is strictly worse than the previous. A parse error at least tells you something broke. A silent stop is harder to catch but doesn't corrupt your work. A hallucination silently corrupts the output while appearing to function normally.

All three shapes share the same root: something breaks at the thinking-to-content-generation boundary. The difference is just what the model does after the break: error out, go silent, or fill in the gap with fabricated content.

Environment
  • Windows 11 Pro + WSL (Ubuntu 24.04 LTS)
  • Claude Code 2.1.169
  • Claude Opus 4.8 (claude-opus-4-8)
  • Still on claude-opus-4-6[1m] for anything real
ynatz · 1 month ago

Update after Fable 5 release

Hours after my previous comment, Fable 5 was released. For balance: in the same environment (WSL2 / Claude Code 2.1.170), Fable 5 has not exhibited any of the three failure shapes so far. This further supports that the issue is specific to the Opus 4.7/4.8 generation rather than the harness.

However, Opus 4.7/4.8 themselves remain unfixed and are still available for selection. Please don't close this as implicitly resolved by Fable 5, as long as these models are being served, this remains a live correctness issue.

sgupge2663 · 1 month ago

Cross-session forensic data (native Windows + Japanese, first-party API)

Independent reproduction of what @fansen, @yurukusa and @ynatz documented here — re-run as a deterministic count across my full local history, so the model/version selectivity comes with hard numbers. Most forensics here are macOS or WSL; this is native Windows + first-party API (@bb774-cyber's is the closest).

Environment: Windows 11, Claude Code CLI 2.1.138–2.1.170 (+ desktop app), first-party Anthropic API (Pro), almost all sessions in Japanese.
Method: deterministic counting over 286 session transcripts (2026-05-13…06-13), fork-copied records de-duplicated by uuid/message.id, plus per-event forensic verification of every stall.

Counts (deduped)

| signature | count | models |
|---|---|---|
| malformed-tool-call injection ("…could not be parsed. Please retry.") | 79 | Opus 4.7: 34, Opus 4.8: 45 |
| retry also failed (visible synthetic error) | 29 (37% of retries) | 4.7 / 4.8 |
| empty assistant msg, stop_reason:tool_use, all blocks empty, outTok>0 (discard residue) | 103 | 4.7 / 4.8 |
| empty end_turn = user-facing silent stop (outTok 484–3849) | 26 (~17 organic) | 4.7 / 4.8 |

Zero on Sonnet 4.6, Opus 4.6, and Fable 5 in the same window (Sonnet 4.6: 805 msgs / 263 tool attempts, clean).

Residue signature (machine-verified, 0 exceptions)

All 79 injections are immediately preceded by an assistant message with stop_reason: "tool_use" but no tool_use block and no text/thinking — the model emitted output tokens (463–1999) that the harness discarded. Same fingerprint as #63583. The 103 empty-tool_use residues pair 1:1 with the injection/retry-failed events (no exceptions).

Version/model exposure — with a significance test

The "4.6 clean → 4.7 onset → 4.8 worst" gradient holds, now with a number on it:

| cohort (Opus only) | tool attempts | malformed |
|---|---|---|
| CLI ≤2.1.149 | 1528 | 0 |
| CLI ≥2.1.152 | 1799 | 79 (4.4%) |
| within 4.7: ≤2.1.149 | 641 | 0 |
| within 4.7: ≥2.1.152 | 692 | 34 (4.9%) |

Session-level Fisher exact p ≈ 3.6e-12; onset on my account 2026-05-27. The injection literal predates 2.1.152 (it's in #61133 at 2.1.145), so it's a real onset, not a new log path — consistent with @yurukusa's quoll-v7 routing decode of #61133.

The silent-stop shape (@ynatz's second shape) is quantifiable

The empty end_turn rows above are the no-error-string version of the same bug: same residue fingerprint (stop_reason set, zero content blocks), just end_turn instead of tool_use, so it reads as "the CLI hung" and gets reported far less.

Sample request_ids (for server-side log correlation)

Discarded tool_use turns — the request the harness threw away (empty residue):

  • req_011CbcnjZLiS8Pi6M9dQPEZC — Opus 4.8, 2.1.159
  • req_011CbUbt57mumNesz2C79FX9, req_011CbUeLDsqFeN6d1CyNaTxz, req_011CbUew21vo1MdYMweBWKTK — Opus 4.7, 2.1.153

Empty end_turn silent stops:

  • req_011CbUf1kXA8LtawY1c2A6vD, req_011CbUZKG6v6LCG3gBfMrQgy, req_011CbUZTsDFvvTSbej4hDSJn — Opus 4.7, 2.1.153 (last two are a back-to-back double silent stop)

Recoverable

All 61 stall-like turns verified; 33 confirmed silent stalls. Recovery was almost always re-sending the same message — context is intact, the model just isn't re-engaged.

Likely root cause: #67765 (accumulator shear in the streaming partial-JSON parser) is the most precise code-level hypothesis I've seen and fits both the tool_use-with-no-block residue and the empty end_turn shape.

Full per-signature breakdown, scripts, and redacted samples are organized and available if a maintainer wants them. Still reproducing on 2.1.170 / Opus 4.8.

TheGreatCBH · 27 days ago

Workaround via a Stop hook (auto-retries with a brevity nudge)

The root cause is the decoder leaking legacy XML (<invoke ...>, <function_calls>) into what should be a pure JSON tool call — triggered by long single-call outputs. The harness already attempts one verbatim retry automatically, but verbatim means the same long call, so it fails again and the turn terminates.

The fix at the hook layer: A Stop hook fires after the turn ends. You can detect the terminal failure signal and block the stop, feeding the model a brevity-focused re-prompt so it retries with a shorter call — splitting a large Write into a skeleton + Edit chunks, or using a one-line commit -m, etc.

Detection signal (empirically verified across 830 real transcripts, 7/7 true positives, 0 false positives):

# Last assistant record in the transcript JSONL
stop_reason == "stop_sequence"
AND text contains "The model's tool call could not be parsed (retry also failed)."

The stop_reason guard is critical — prose that merely discusses this error has end_turn or tool_use, not stop_sequence, so false positives are zero.

Hook response:

{ "decision": "block", "reason": "Your tool call failed to parse (length-correlated decoder bug). Re-issue it now but KEEP IT SHORT — no long heredocs, one simple call. If it keeps failing, split into multiple small calls." }

A per-session counter on disk caps retries at MAX_RETRIES = 2; stop_hook_active in the payload prevents infinite loops.

---

I've packaged this up as a drop-in hook with tests and install instructions:
https://github.com/TheGreatCBH/claude-code-toolcall-recovery

Appears to be the first working implementation of this approach — the community discussion in #58182 explored StopFailure + asyncRewake but nothing was shipped. This works today with the existing Stop hook.

TheGreatCBH · 27 days ago

Client-side auto-recovery workaround via Stop hook

(Root fix is server-side; this workaround removes the need for manual "please resend" after each failure.)

Two failure shapes are now handled:

Shape 1 — the classic retry also failed terminal error (visible in the UI)

Shape 2 — the model emits <invoke name="..."><parameter name="command">...</parameter></invoke> as literal text in its response and ends the turn with end_turn. The tool is never executed; the harness sees a normal turn end and does nothing. This is what you see when the XML markup is rendered visibly in the conversation and work just... stops.

How the hook works:

  1. Claude Code's Stop hook fires after every turn.
  2. The hook reads the session transcript (.jsonl) and checks for either failure shape.
  3. On a match it returns {"decision":"block","reason":"..."}, which feeds a brevity-focused re-prompt back to the model — the model retries automatically with a shorter call.
  4. A per-session counter caps retries at MAX_RETRIES=2 and stop_hook_active prevents infinite loops.

Verified across 830+ real transcripts — 40 true positives total, 1 accepted false positive (model explaining the bug with a full XML code example; bounded by the retry cap).

Drop-in hook with tests and install instructions:
https://github.com/TheGreatCBH/claude-code-toolcall-recovery

Two lines to install:

cp stop_recover.py ~/.claude/hooks/stop_recover.py
# then add to ~/.claude/settings.json → hooks → Stop
ynatz · 26 days ago

Persona as a factor that steers failure mode

Building on my [three failure modes comment](#issuecomment-4672036498) and a related observation I just posted on #64260

I've been investigating why my environment consistently hits failure mode 3 (hallucination / fabricated user intent) rather than mode 2 (silent stop). A possible explanation: persona configuration determines which direction the model fails when a tool boundary breaks.

The reasoning

When a tool call can't be generated correctly, the model still needs to produce some output. Without a persona, the path of least resistance is silence (mode 2: the turn ends with no visible output). With a persona that includes proactive-behavior directives ("anticipate what the user needs," "address issues before they're encountered"), silence is inconsistent with the character the model is maintaining. The model may instead fill the gap by fabricating a continuation of the conversation, which surfaces as mode 3.

In other words, the tool boundary corruption is the same underlying failure in both cases. What differs is the recovery behavior: the persona's framing may push the model toward generating plausible conversational output instead of stopping.

Supporting data

Same environment (Ubuntu 24.04 WSL, Claude Code, Japanese, custom development framework, Agent Teams, max effort), same persona:

| Model | Shape 1 (parse error) | Shape 2 (silent stop) | Shape 3 (hallucination) |
|---|---|---|---|
| Opus 4.6 (1M) | not observed | not observed | not observed |
| Opus 4.7 | observed | observed | not observed |
| Opus 4.8 (1M) | observed | observed | recurring |
| Fable 5 | not observed | not observed | not observed |

A colleague using Opus 4.8 in Japanese without persona configuration reports no fabrication incidents. This is a single data point, but it's consistent with the hypothesis: no persona means no pressure to fill the gap with fabricated conversation, so broken tool calls surface as mode 1 or 2 instead of escalating to mode 3.

Implication for triage

If this is right, the three modes aren't independent. They're outcomes of the same tool-boundary corruption, with the model's system prompt influencing which mode manifests. Users with minimal system prompts may experience the same underlying bug rate but never see mode 3, making the issue appear less severe from their perspective.

tznthou · 22 days ago

This started for me on May 23rd. Claude Code began freezing mid-task — not crashing, freezing: the model would decide to call a tool, and then nothing came out. One spinner ran 21 minutes before I accepted something was genuinely broken. Three days of digging traced it to a single boolean in a minified tokenizer; the only clean way out at the time was dropping to Opus 4.6. So for anyone still stuck — here's the direction I wish I'd had.

The part that took me longest to accept: the symptoms converge but the root causes don't. "Tool call could not be parsed", empty {} args, a turn that goes quiet, a 20-minute thinking spin — these are several different bugs wearing the same face. Two broad families:

  • Client-side streaming-parser drop — the CLI's partial-JSON parser drops a string token when a tool argument is split across a streaming-chunk boundary, collapsing the input to {}. @in4mer root-caused this precisely in #67765 ("accumulator shear").
  • Model/server-side — thinking that stalls or loops, extended-thinking serialization defects, malformed markup. @yurukusa's cc-safe-setup splits these into sub-patterns (12A–12D). A client can't fix these.

If you don't specifically need 4.7/4.8: dropping to Opus 4.6 is the cleanest escape. It's what the community keeps landing on (/model claude-opus-4-6[1m]) and what got me unstuck. To be precise — I can't prove 4.6 is immune; this is empirical, the cluster shows up on 4.7/4.8 and 4.6 sidesteps it. The cost is real: you give up 4.7/4.8 capability. But if you can live with that, it's the lowest-risk floor.

If you do need 4.8, evap-shield patches the one corner that's actually client-side fixable — it flips the parser flag so the dropped-string path can't form {} at the source. Honest scope: it fixes only the client-parser corner (in4mer's); the thinking-side failures it can't touch; and it's unit-verified (760 truncation cases, 0 regressions), not end-to-end. It's a binary patch — real setup and risk to weigh, and I'd genuinely rather you read the boundary write-up before running it than patch on impulse. When it's not enough, the fallback is still 4.6.

How to tell which one you're hitting, so you don't burn time on the wrong fix: are the args actually arriving as {}? → client-parser corner, patchable. Does /clear recover you? Per @yurukusa: yes → context-poisoning (12A); no → serialization (12B), tied to the build. Long thinking spin with no {}? → model-side; the patch won't help there.

Why this is showing up now, and not back in May: I didn't want to hand anyone something half-understood. So I kept checking. Every time Claude Code updated, I re-ran the binary diff to see whether the parser had been touched — through 2.1.187, across every release since, that byte hasn't moved once. That's what convinced me this isn't a "wait for next week's build" situation. I spent the same months mapping where the patch doesn't reach — the failures it can't help with — because shipping a fix without its boundary felt worse than not shipping. That's the honest reason it's here now.

One more thing, plainly: the tooling I used to investigate this runs on the same affected models, and it hit these failures mid-investigation. I don't think that voids the findings — but it's exactly why I kept everything checkable from the outside instead of asking you to trust my read.

It's all in the repo — github.com/tznthou/evap-shield — and the write-up is as clear about what it doesn't fix as what it does.

Credit where it's due: I reached the parser root cause independently, but @in4mer's #67765 is the sharpest writeup of it, and @yurukusa's cc-safe-setup is doing the real work of helping people identify which sub-pattern they're on and recover. evap-shield is one corner; theirs cover others it can't. Genuinely grateful to both — this looks like a community converging on a hard bug, not competing tools.

MufanQiu · 21 days ago

For anyone who wants to stop hand-typing "continue" until this is fixed upstream: I put together a Claude Code Stop hook that catches this exact "tool call could not be parsed (retry also failed)" end-of-turn and auto-continues the session. It recognizes both the give-up message and the case where the malformed call leaked into the text, then nudges the model to resend it correctly. Has a retry cap + time window so it can't loop forever, and it strips code blocks first so it won't fire when you're merely discussing tool-call XML.

Third-party, not affiliated with Anthropic; just a stopgap. https://github.com/mufanq/claude-code-toolcall-recovery — feedback welcome.

notch-0314 · 15 days ago

Same issue here — reproduced consistently in a long session today.

Environment

Model: Claude Opus 4.8 (1M context) — claude-opus-4-8[1m]
Interface: VS Code extension
OS: macOS (Darwin 23.0.0)
Shell: zsh
Symptom
Mid-session, the model started emitting tool calls with corrupted control tokens: the function_calls opener came out as the plain word court, and invoke / parameter lost the antml: namespace prefix. The parser rejected these with:

Your tool call was malformed and could not be parsed. Please retry.

Key problem: it does not recover. Once the first malformed call appeared, the model kept reproducing the same broken format on subsequent tool calls, even after I explicitly pointed out the cause. Retries failed the same way. It only produced a correct antml:invoke intermittently. This self-reinforcing loop blocked the session and I had to abandon the task.

Expected
Tool calls should always be emitted with correct antml:invoke / antml:parameter tags, and the model should be able to recover after a single malformed call instead of looping.

Possibly related: #72352 (stray court token + non-namespaced <invoke>), #72015 (Opus 4.8 1M dropped antml: prefix), #71952.

tznthou · 13 days ago

Three data points from two weeks of transcript forensics on CJK-heavy sessions (Opus 4.8)

Sharing these in case they help others narrow down what they're hitting. Environment: Claude Code CLI 2.1.185–2.1.199 across these cases, Opus 4.8 (incl. max effort), macOS, Traditional-Chinese-heavy long sessions, high tool density.

1. The stray token before the leaked <invoke> looks like a pattern, not noise

#64658 already notes stray court/count tokens (court also seen in #71952 / #72352, and by notch-0314 above). Adding two more first-hand samples: (2026-06-22, CLI 2.1.185) and call (2026-06-25, twice in one session; independently reported in #72015). Combined set: , call, court, count — across CLI and Desktop, across Chinese/Japanese/Korean-heavy sessions, always c-initial, always sitting where the tool-call opener should be. Speculative, but it reads like the opener's control token decoding into nearby ordinary tokens rather than being dropped outright. Might be a lead for whoever owns the serializer side.

2. Confabulation can masquerade as a security alert — check artifacts before believing "I blocked a prompt injection"

A shape we verified on 2026-07-03 (CLI 2.1.199, Opus 4.8 max effort, 2.5h session), related to the #64409 cluster (currently labeled stale, for what it's worth):

  • Mid-session, the model twice told the user it had detected and blocked "a prompt injection trying to change my persona" in the previous message. Transcript check: the previous message was a clean ls tool result plus hook logs. No injected content exists anywhere in the transcript.
  • Same session, worse: within a single thinking block the model planned a smoke test, "ran" it, and "verified" its outputs — zero tool calls issued, and the output directory never existed on disk. It then tried to Read the imagined files, got honest "File does not exist" errors, and concluded the environment was broken ("Read is failing, Bash output may be fabricated") — which it reported to the user as "this session is degraded: two injections, truncated output, broken Read".

Every claim failed the claim-vs-artifact check: tool results were clean, hooks healthy, the "created" files never existed. Practical takeaway: when the model announces an injection or environment corruption, diff its claims against the transcript before acting on the alert. This shape is nastier than fake tool successes because it arrives dressed as diligence.

3. Corroborating the self-reinforcing loop

Our 2026-06-22 case behaved exactly as notch-0314 and #64658 describe: once the first malformed call appeared, retries reproduced it; only a fresh session cleared it. #64658's "self-reinforces on replay" matches — the malformed turn poisons the context it replays into.

---

We maintain the forensics method and a client-side byte patch at evap-shield. Honest scope note: the patch fixes exactly one client-side sub-shape (the streaming parser dropping tool args to {} — the primary issue in in4mer's #67765 analysis). It cannot help with the model-side shapes above — antml-prefix drops and confabulation are upstream of anything a client can patch. Where the repo may still be useful there is triage: fingerprinting which shape you're actually hitting (empty {} args vs. leaked XML vs. confabulated results), so you know whether to patch, retry, restart, or re-verify the model's claimed work.

If anyone tries either piece, reports on whether it holds up in your environment — especially negative results — would be genuinely useful.

adf0881-dev · 10 days ago

Reproducing consistently on Opus 4.8 in the Claude Code desktop app. Two conditions correlate strongly here, and one of them may be a useful signal:

  1. It starts well before the context window is exhausted, and correlates with the number of images loaded into context. In long sessions that drive the browser-automation MCP (claude-in-chrome / computer-use) and load many screenshots, malformed tool calls begin appearing with plenty of context headroom still left, and get more frequent toward the end of the session. So it does not look like a hard token-limit failure — image-heavy context seems to be an independent trigger.
  1. The malformed output matches what others describe here: a stray court / course prefix and a dropped antml: XML namespace on the invoke / parameter tags, so the parser rejects the call. A simpler retry usually succeeds.

Both Bash tool calls (especially multi-line command strings / commit messages) and MCP tool calls are affected. Impact: it breaks in-flight multi-step work (mid browser automation, mid git commit) and repeatedly forces the user to abandon the current session and reopen the task in a fresh one — which is costly for long, stateful workflows.

1llum1n4t1s · 3 days ago

Workaround: I've switched to Sonnet 5 (MAX) instead of Opus, sacrificing cost-performance, to avoid this issue.