Claude Code sends empty text content blocks to Anthropic API, causing 400 errors

Resolved 💬 3 comments Opened Feb 5, 2026 by em Closed Feb 5, 2026

Description

When a hook returns a deny/block decision, Claude Code constructs the retry API request with an empty text content block. The Anthropic API rejects this with 400. Since the conversation state doesn't change between retries, this creates an infinite loop that requires Ctrl+C to break.

Evidence

The transcript sequence is:

● Ran 1 stop hook
  ⎿  Stop hook error: VIOLATIONS DETECTED (1 total): ...
  ⎿ API Error: 400 {"type":"error","error":{"type":"invalid_request_error",
    "message":"messages: text content blocks must contain non-whitespace text"}}

The hook evaluated the agent's response (found patterns in its text), returned a deny decision, and then IMMEDIATELY the API error occurs with no agent response in between. Claude Code's client is generating the empty text content block when assembling the retry request, not the model.

Error message

API Error: 400 {"type":"error","error":{"type":"invalid_request_error",
"message":"messages: text content blocks must contain non-whitespace text"}}

Expected behavior

Claude Code should not include empty/whitespace-only text content blocks in API requests when constructing retry requests after hook deny decisions.

Actual behavior

The retry request contains an empty text content block. The API rejects it. Subsequent retries produce the same malformed request, creating an infinite unrecoverable loop.

Environment

  • Claude Code v2.1.31
  • Observed repeatedly across multiple sessions

View original on GitHub ↗

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