claude-code - 💡(How to fix) Fix Regression (2.1.147–2.1.150?): resuming an extended-thinking session after a CC update/model-switch → unrecoverable 400, session bricked

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

API Error: 400 messages.<N>.content.<M>: thinking or redacted_thinking blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response. API Error: 400 The content[].thinking in the thinking mode must be passed back to the API.

Root Cause

Root cause (hypothesis)

Code Example

API Error: 400 messages.<N>.content.<M>: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.
API Error: 400 The content[].thinking in the thinking mode must be passed back to the API.
RAW_BUFFERClick to expand / collapse

Summary — likely a regression introduced between 2.1.146 and 2.1.150

Extended-thinking sessions that resumed cleanly for ~a week on 2.1.146 began throwing an unrecoverable 400 immediately after the first update in ~4 days (to 2.1.150). The transcript shows zero 400s on 2.1.146 and the first 400s appearing once the session crossed into 2.1.150, with the model unchanged — which points squarely at a regression in the 2.1.1472.1.150 range. A bisect of that range is likely the fastest path to the cause.

The failure: a long-running session becomes permanently unrecoverable with a 400 when the message history (including extended-thinking blocks) is replayed on resume/compaction after the environment underneath it has changed — a CC version update mid-session (primary trigger here), or a model switch mid-session. The thinking-block signatures from prior assistant turns are no longer accepted by the API, and CC then retries the identical rejected payload indefinitely instead of degrading. The only escape is to abandon the session.

Two error strings observed:

API Error: 400 messages.<N>.content.<M>: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.
API Error: 400 The content[].thinking in the thinking mode must be passed back to the API.

Impact

  • Session-fatal and unrecoverable. Once a rejected turn is in history, every subsequent request re-sends the same invalid thinking block and re-fails. /compact does not help (the broken turn is still in the rebuilt payload). Switching the model does not help (it re-sends the same bytes). We lost a very large multi-day session this way.
  • Triggered by normal, expected actions: letting CC auto-update, or changing the model — both of which users do routinely across a long session.

Forensic evidence (from the session transcript)

One ~56,600-record session that died:

  • Spanned four CC versions as it auto-updated: 2.1.146 → 2.1.150 → 2.1.152 → 2.1.154.
  • Zero 400s while on the starting version 2.1.146.
  • First 400 cluster appeared after the update to 2.1.150, with the model unchanged (still the same Opus version) — so a client version change alone triggered it.
  • Final, fatal 400 cluster appeared on 2.1.154, which also coincided with a model switch (4.7 → 4.8) done via exit → update → resume.
  • Every one of the 3,402 thinking blocks is persisted in the transcript jsonl as signature-present, plaintext-empty ("thinking": ""). That's fine while the turn is live (real text held in memory), but it means any rebuild-from-transcript must reconstruct the block, and the reconstructed block's signature is validated against a changed environment.

Root cause (hypothesis)

Extended-thinking block signatures are bound to the producing model (and apparently sensitive to client version/serialization). On resume or compaction, CC rebuilds the message array from the transcript and replays prior assistant turns' thinking blocks. If the model or the client changed since those blocks were produced, the API rejects them as "modified / must be passed back." CC has no fallback — it re-sends the same payload on every retry.

The defect worth fixing (even if the trigger is "expected")

The Anthropic API allows omitting thinking blocks from non-latest assistant turns. So on a thinking-block 400, CC could recover automatically instead of bricking the session:

  1. On a thinking/redacted_thinking 400, strip thinking blocks from prior (non-latest) assistant turns in the rebuilt history and retry.
  2. For the latest-assistant-message in-turn case, retry that step with interleaved thinking disabled.
  3. On any model switch or client-version change across a resume, proactively drop persisted thinking blocks from prior turns (they're only valid for the environment that produced them) rather than replaying them.

Any one of these turns a session-killer into a transparent, recoverable degrade.

Repro

  1. Start a long session with extended thinking / high reasoning effort enabled.
  2. Let it run long enough to compact and/or let CC auto-update at least once (or exit, update the model, and --resume).
  3. Continue working (especially tool-loop turns).
  4. Observe the 400 above; observe that retry, /compact, and model-switch all fail to recover.

Environment

  • Claude Code CLI 2.1.1462.1.154, macOS (darwin)
  • Models: Opus 4.7 and 4.8, high reasoning effort, extended/interleaved thinking on

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING