[BUG] CLI 2.1.154 builds invalid request after context ops (compact/clear/model-switch): system role at messages[0], and modified signed thinking blocks → 400 Error -> Wedged
Summary
After a context operation (compaction, /clear, or a /model switch) on a long-lived session, the CLI constructs an invalid request body that the Anthropic API rejects with HTTP 400. Two distinct variants observed. Both are terminal for the session: every subsequent prompt rebuilds the same malformed request and re-fails, so the session cannot recover except by /clear (which discards context — and variant 2 then recurs on the next complex turn).
Environment
- OS: macOS 25.4.0 (Darwin), arm64
- Claude Code CLI: v2.1.154
- Plan: Max
- Model: Opus 4.8 (1M context) — selected via
/model
Variant 1 — system role placed at messages[0]
Trigger: a long session with multiple compaction summaries, then a /model switch, then the next user prompt.
API Error: 400 messages.0: use the top-level 'system' parameter for the initial system prompt
Sequence from the transcript:
- assistant idle ("No response requested.")
- user runs
/model→ sets "Opus 4.8 (1M context)" - user types a normal prompt
- → 400
The reconstructed request placed a message with role system (a compaction summary) at messages[0]. The API requires the initial system prompt in the top-level system parameter, never as a messages entry.
Variant 2 — signed thinking blocks modified (on a fresh /clear session)
Trigger: a brand-new session created by /clear, then the agent reads prior transcript history and invokes a skill across many interleaved extended-thinking + tool_use turns.
API Error: 400 messages.3.content.9: `thinking` or `redacted_thinking` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.
Every assistant turn in the transcript carried a properly signed thinking block (verified: each had a non-empty signature). The API requires signed thinking blocks to be returned verbatim, so the client mutated the content of messages[3].content[9] during request assembly. Because this occurred on a fresh /clear session (not a resume of a corrupted transcript), it is not residual corruption carried over from a prior session.
Impact
Both variants leave the session permanently stuck — no recovery path except /clear, and Variant 2 recurs on the next complex thinking+tool session. A heavily-used long session can be lost without warning right after a routine /model switch or /clear.
Likely common root
Request-array reconstruction after a context operation (compact / clear / model-switch / skill injection) corrupts preserved blocks: it misplaces the system prompt into messages[0], and it mutates previously-signed thinking blocks instead of re-sending them verbatim.
Related
Same session-continuity / model-and-context-handling area as #60913 (literal [1m] model name on resume → 404 → silent 200K fallback), still open and confirmed through v2.1.150.
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗