AskUserQuestion: cancelling during extended thinking poisons the whole session with 400 'thinking blocks cannot be modified' (2.1.153); concurrent prompts overwrite each other

Status Closed — not planned
Reported on v2.1.153
Maintainer reply None cached
Activity 11 comments · opened May 28, 2026 · closed Jul 10, 2026

Summary

When extended thinking is enabled, cancelling/rejecting an AskUserQuestion prompt poisons the entire session: the next request fails with API Error: 400 ... 'thinking' or 'redacted_thinking' blocks in the latest assistant message cannot be modified, and then every subsequent message returns the same 400. The session is unrecoverable — the only escape is /exit.

There is a second, contributing bug that makes the cancel far more likely: multiple AskUserQuestion tool calls emitted in a single streamed assistant response render concurrently and overwrite each other on screen, so the visible question changes while the user is mid-answer — prompting an instinctive Escape/cancel, which then triggers the 400 above.

Environment

  • Claude Code 2.1.153 (native install) — latest at time of filing
  • macOS (Darwin 25.x)
  • Extended thinking enabled, Auto permission mode
  • Reproduced across three consecutive sessions in an ~18-minute window

Bug 1 — concurrent AskUserQuestion prompts overwrite each other

In one streamed assistant response, the model emitted more than one AskUserQuestion tool_use interleaved with other tool calls, without waiting for an answer to the first. Inspecting the session transcript (~/.claude/projects/<proj>/<id>.jsonl) via the uuid/parentUuid chain:

AskUserQuestion (3 questions)   13:17:04   <- prompt A, never answered yet
  assistant Read                13:17:26   <- continues WITHOUT a tool_result for A
  assistant (thinking)
AskUserQuestion (2 questions)   13:17:39   <- prompt B fires; A still pending
  assistant Read                13:18:03
...
tool_result for prompt A        -> "the tool use was rejected"
tool_result for prompt B        -> "the tool use was rejected"

Both AskUserQuestion blocks were pending simultaneously. The second prompt rendered over the first while the user was still answering it → the question visibly changed mid-interaction.

Expected: AskUserQuestion should be a hard barrier — ask one, stop, wait for the answer before any further tool call or a second AskUserQuestion.

Bug 2 — cancelling AskUserQuestion during extended thinking → unrecoverable 400

Cancelling/rejecting the AskUserQuestion produces:

API Error: 400 messages.1.content.11: `thinking` or `redacted_thinking` blocks in the
latest assistant message cannot be modified. These blocks must remain as they were in
the original response.

After this, every subsequent user message returns the identical 400, because the corrupted assistant turn (with the modified signed thinking block) stays in history and is re-sent on each request. /exit is the only way out. (/clear or a rewind to before the poisoned turn would also work but most users don't discover that.)

Repro steps

  1. Start a session with extended thinking enabled.
  2. Get the assistant into a flow that emits an AskUserQuestion (e.g. an interactive spec/PRD-iteration flow). Bug 1 makes this reliably produce multiple prompts.
  3. Cancel/Escape the question (or reject the tool use) — natural reaction when the prompt changes under you.
  4. Send any further message → 400 ... thinking blocks cannot be modified.
  5. Every message thereafter → same 400. Session dead.

Expected

Cancelling an AskUserQuestion should leave the session usable. The client should drop/strip the un-finalised assistant turn (or its stale-signature thinking blocks) rather than re-sending a modified thinking block. This mirrors the 2.1.152 fix ("sessions getting stuck after a model or login switch left stale thinking-block signatures in history; now stripped proactively") — but that fix only triggers on a model/login switch, not on AskUserQuestion cancel, so this path remains broken in 2.1.153.

Impact

High. A single mis-click/Escape on a question — especially when Bug 1 makes the prompt move under the user — permanently bricks the session and loses in-progress context unless the user knows the /exit (or /clear/rewind) escape hatch.

Related

  • #10199 (open) — general thinking-block 400
  • #12743, #24662, #26684, #21289, #22217 (closed) — thinking-block / unrecoverable-session 400s via other triggers (compaction, empty content block, 100% context). This issue adds the AskUserQuestion-cancel trigger and the concurrent-AskUserQuestion contributing factor, confirmed on 2.1.153.

View original on GitHub ↗

11 Comments

AlexErrant · 3 months ago

Just ran into the same error, except I didn't cancel out of the question or have concurrent questions. Just 1 question, then kablooey.

<img width="1896" height="1010" alt="Image" src="https://github.com/user-attachments/assets/1f8e0c17-21a5-4008-a386-8942ec9bdb19" />

mrz1836 · 3 months ago

I'm getting the same error
"API Error: 400 messages.1.content.14: thinking or redacted_thinking blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response."

Then my session/chat becomes unusable after that state. Just started happening today on VS plugin 2.1.153

Rabusek · 3 months ago

Same error.

Jorgemunera · 3 months ago

Same error

davidalejandroaguilar · 3 months ago

Bricking every conversation

Debaerdm · 3 months ago

Same on Claude Desktop 2.1.149 / opus[1m], effort=max. Trigger here was an AskUserQuestion turn interleaved with parallel tool_use + an MCP tool; session then permanently wedged — 20 consecutive identical 400s over ~19 min, every new message failing. Transcript confirms all thinking blocks stored as empty text + retained signature (cf #63147). Full analysis: https://github.com/anthropics/claude-code/issues/63354#issuecomment-4567903321

yurukusa · 3 months ago

Independent confirmation that this is structurally a sub-pattern of Cluster 13 (Extended-Thinking Session Wedging) rather than a standalone bug — and a complementary trigger to the resume-side corruption at #63147.

Cluster framing

Tracking this as sub-pattern 13B in the cluster I documented across the past 36 hours: extended thinking + four distinct trigger conditions, all converging on the same 400 ... thinking blocks cannot be modified failure. The four sub-patterns share one root failure mode (thinking-block serialization not surviving the round-trip), but have different trigger surfaces and therefore different operator-side workarounds:

  • 13A — resume serialization corruption (#63147, 33 reactions, canonical root-cause analysis by @jdrolls)
  • 13B — cancel-during-AskUserQuestion poisoning (this issue)
  • 13C — parallel-tool-batch cancellation corruption (#63192)
  • 13D — intermittent signed-thinking-block replay (#63335 + 10+ duplicate-flagged reports)

Field guide articulating all four sub-patterns with the recovery surface limits and the operator-side advisory hooks: Extended-Thinking Session Wedging — A 36-Hour Surge with 4 Sub-Patterns and Operator-Side Recovery Paths (MIT, ~2,800 words).

What 13B uniquely surfaces

Beyond the cancel-as-trigger axis, this issue exposes a second, compounding bug that the other three sub-patterns don't have: multiple AskUserQuestion blocks emitted in a single streamed assistant response render concurrently and overwrite each other in the TUI. The operator sees one question, answers it, and the next question appears as if it were a follow-up — except the answer was applied to a different prompt than the one visible. The cancel/Escape reflex is then trained: you press Escape because the UI shows something you didn't expect, which fires the cancel that triggers the 400.

@Debaerdm's reproduction (interleaved with parallel tool_use + an MCP tool, then 20 consecutive identical 400 failures) and @AlexErrant's "just 1 question, then kablooey" case bracket the trigger surface: the cancel/error path on AskUserQuestion poisons the in-flight assistant message's thinking blocks even without explicit user cancellation when the question handling itself errors.

Operator-side defenses (cc-safe-setup)

The hook shipped 2026-05-29 (PR #445, 54 tests passing) targets sub-pattern 13A at SessionStart — it detects the precursor shape (thinking blocks with empty text but non-empty signature) in the transcript before resume actually fires the 400. That hook won't catch 13B, since 13B fires mid-session rather than at resume.

The 13B advisory is in design: a PreToolUse hook on AskUserQuestion that surfaces a one-line stderr advisory the first time AskUserQuestion fires in an extended-thinking session, naming sub-pattern 13B and the "don't hit Escape, answer the question (even if the answer is Skip) rather than cancelling" workaround. Rate-limited to one advisory per session to avoid noise. Targeting a June 2026 ship.

For sessions that have already wedged, the post-hoc transcript repair tool miteshashar/claude-code-thinking-blocks-fix is the recommended entry point — it operates on the on-disk transcript and produces a repaired version that can resume cleanly. The hooks above are preventive; that tool is the right move when you're currently in a wedged session.

What I'm watching for

The trigger surface for 13B is documented (cancel/error on AskUserQuestion), but the second bug (concurrent-overwriting AskUserQuestion blocks) feels like a separate concurrency issue in the streaming-response renderer rather than a thinking-block problem. If the second bug ships independently of the thinking-block fix, this sub-pattern would naturally degrade in severity (operators wouldn't be trained to reflex-cancel). I'm tracking both surfaces in the cluster registry: cluster-tracker.html#cluster-extended-thinking-wedge.

MMoMM-org · 3 months ago

some more feedback.. manual without Claude Code analysing itself
a) I did a clear after a long session without 400... and received an infant.. it is not the skill etc.. i use that all the time
<img width="1138" height="898" alt="Image" src="https://github.com/user-attachments/assets/1f98dbfd-2175-4859-bac1-e34fa2f42109" />
after Invalid tool parameters I got
Background command "Minimal shell probe" completed (exit code 0)
⎿  API Error: 400 messages.1.content.13:
thinking or redacted_thinking blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response.
I wonder what triggered the degrading.. never seen that till now
b) an other session errored out on 400.. restarted claude and told him to look at the last session log to figure out where he got stock.. because he got stuck somewhere during a rewrite
after several errors during tool calls I got
<img width="1654" height="367" alt="Image" src="https://github.com/user-attachments/assets/0bdc796d-51a1-4550-abaf-0642ef26713e" />
that would be 13C — Parallel-tool-batch cancellation corruption (#63192):

yurukusa · 3 months ago

@MMoMM-org — both data points are useful, and together they widen the trigger surface in two specific directions worth tracking separately.
This is the part that doesn't fit cleanly into 13A–13D as currently framed, and I want to flag it as a candidate new sub-pattern rather than fold it into the existing axes prematurely.
The cluster's working hypothesis is that the corruption mechanism is thinking-block signature surviving a round-trip where the underlying content fragments did not. All four of the documented sub-patterns share a moment-of-divergence between "block as the server signed it" and "block as the client replays it":

  • 13A — resume serialization rewrites the blocks
  • 13BAskUserQuestion cancel interrupts the in-flight assistant message
  • 13C — parallel-batch cancellation interrupts a sibling block
  • 13D — intermittent signed-block replay (root cause unclear; #63335 + dupes)

Your case fires without any cancellation surface — /clear after a long session, then an Invalid tool parameters from a Bash probe on the first turn of what should be a fresh context. Two ways this can map onto the existing model, and they have very different implications:

  1. /clear is not actually wiping the thinking-block state that 13D needs to corrupt (i.e. the post-clear messages.1 is being replayed against a server expecting messages.N). If true, this is a /clear reliability bug that exposes 13D rather than a new sub-pattern.
  2. The "long session" itself accumulated a corrupted block during normal operation (no cancel, no resume), and /clear is irrelevant — the first new tool call just happened to be the one that triggered re-validation. If true, this is genuinely new: corruption without an obvious interruption surface, which would shift the model from "validate-on-cancel" to "validate-always".

The way to distinguish them is whether the 400 references messages.1.content.13 (post-clear context, fresh) or a much higher messages.N.content.M (pre-clear context still in play). Your screenshot shows messages.1.content.13 — which is at first glance the "clear failed to actually clear" reading. But the messages.1 index also resets to 1 after /clear even when the conversation is genuinely fresh, so the index alone can't disambiguate. If you still have access to the session, can you check whether the error appears on the very first user message post-/clear, or whether several turns succeeded before it surfaced?
If it's the very first user message → that's strong evidence for sub-pattern (1) (/clear not wiping properly).
If several turns succeeded first → sub-pattern (2) (validate-always corruption) and we'd file a new candidate.
This matters because the operator-side mitigation diverges: (1) means "don't trust /clear as a recovery mechanism — /exit is the only escape", which is what we'd already advised. (2) means the corruption is happening during normal operation in ways the user can't trigger or prevent, which would meaningfully change the severity assessment of the cluster.
This one does sit cleanly inside 13C as @Benjamin-Sterrett's confirmation of cross-tool corruption just demonstrated (their comment on #63192 adds a Bash + TaskCreate mixed-batch repro that kills the "Bash-specific" hypothesis). "Several errors during tool calls" is exactly the sibling-cancellation surface — if any of the errored tool calls were in a parallel batch, the cancellation cascaded onto the rest of the batch including the thinking blocks. Your read is the right one.
The "looking at the last session log to figure out where he got stuck" framing is also a useful repro pattern, because it sets up exactly the conditions 13C needs: high parallelism (file reads + greps + status checks) early in the session to reconstruct context, with a non-trivial probability of one of them erroring on a stale path. I'm folding "session-recovery / log-analysis startup" into the field guide's amplifier list, since this isn't the first time it's surfaced in 13C reports.
The (a) data point is the one I'd most like to characterize precisely. If you encounter the post-/clear 400 again:

  • Capture the exact messages.N.content.M index from the 400 body (not just messages.1)
  • Note whether any successful turns happened post-clear before the failure
  • Note whether the in-flight tool call when the failure surfaced was in a parallel batch or a single call

Those three data points distinguish (1) from (2), and if it's (2), it's a meaningfully new pattern worth its own issue. If it's (1), it folds into the existing /clear-unreliability advisory.
Either way — thank you for the careful follow-up. The cluster framing only works if reports like yours surface the edges where the four sub-patterns don't fully account for what people are seeing.

zschaeff · 2 months ago

Likely-duplicate report #64525 points here — adding its evidence so it isn't lost when that one closes.

Same core defect as Bug 1 (stacked tool-use prompts overwriting each other), but surfaced via permission/approval prompts instead of AskUserQuestion.

Repro: in --permission-mode auto, a prompt that spawns 4+ parallel subagents, each issuing several approval-gated WebFetch calls, produces a burst of stacked approval prompts. While holding on the first prompt (~30s, no keypress), it swapped at least twice — and on review of a screen recording, both the URL shown and the surrounding prompt content change in place to a different pending tool call. So an approval keystroke can land on an action the user never intended to approve — the same "prompt visibly changes mid-interaction" mechanism described here, just with a permission approval rather than an AskUserQuestion.

Two things that may help the maintainers:

  • Screen recording available showing the URL + prompt content swap in place — concrete video evidence for the overwrite behavior.
  • Reproduced on 2.1.158 (still present after the 2.1.153 work) using a fully neutral prompt with zero autonomy-inviting language, so this isn't user-induced.

Supports the suggested fix: AskUserQuestion / permission approval should be a hard barrier — one prompt on screen at a time, no second prompt rendering over a pending one. I did not hit the Bug 2 session-poisoning 400 (I held rather than cancelled), but the trigger path is the same.

Repro details and the exact prompt are in #64525.

github-actions[bot] · 1 month ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.