[BUG] Stop hook blocks with 'continue: true' fail with API error when response contains thinking blocks

Resolved 💬 3 comments Opened Nov 26, 2025 by em Closed Nov 29, 2025

Bug Description

When a stop hook returns {"decision": "block", "continue": true, "reason": "..."}, Claude Code attempts to inject the reason message into the assistant's previous response. This fails with an API error when that response contains thinking blocks.

Error Message

API Error: 400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.19.content.18: \`thinking\` or \`redacted_thinking\` blocks in the latest assistant message cannot be modified. These blocks must remain as they were in the original response."}}

Root Cause

  1. Stop hook executes and returns block decision with continue: true
  2. Claude Code attempts to inject the reason message by modifying the assistant's last message
  3. API correctly prohibits modification of thinking blocks (they are immutable after generation)
  4. Injection fails and creates retry loop

Expected Behavior

When a stop hook blocks with continue: true, the reason message should be delivered without modifying the assistant's message. Options:

  • Deliver as separate system message
  • Detect thinking blocks and use alternative injection mechanism
  • Append without modifying existing content blocks

Actual Behavior

Claude Code tries to modify the assistant message containing thinking blocks, API rejects with 400 error, creates retry loop.

Environment

  • Stop hook configuration: Valid JSON output with decision/continue/reason fields
  • Thinking mode: interleaved
  • Hook output validated with bash -n (syntactically correct)

Workaround

None available from stop hook side - this requires fix in Claude Code's hook processing logic.

Related Issues

Possibly related to #9486 (system-reminder injection breaking thinking blocks)

Reproduction

  1. Configure stop hook that returns {"decision": "block", "continue": true, "reason": "test"}
  2. Generate assistant response with thinking blocks
  3. Stop hook fires and attempts injection
  4. Observe API 400 error about thinking blocks cannot be modified

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗