Session permanently broken: 'cache_control cannot be set for empty text blocks' after image upload
Summary
After sending an image with no caption text, Claude Code returned an API 400 and the session became permanently unrecoverable — every subsequent prompt (text or image) returns the same 400.
Error sequence
- User sent a screenshot inline (no caption text)
- Assistant turn returned:
````
API Error: 400 messages.338.content.1.text: cache_control cannot be set for empty text blocks
- Every following message (text-only or image+text) returns:
````
API Error: 400 messages: text content blocks must be non-empty
Session had 338+ messages at the point of failure. Running on claude-opus-4-7 with auto permission mode.
Likely cause
The first error suggests Claude Code attached a cache_control breakpoint to a text block that ended up empty after the image upload was processed. Once the bad block lands in the persisted conversation history, every subsequent request to /v1/messages re-sends it and is rejected with the same 400.
Impact
The session is unrecoverable — /resume reloads the same corrupted history and reproduces the error immediately. For long-running sessions (mine had 338+ messages of accumulated context), restarting fresh is costly.
Workaround
Start a fresh claude session. Use /resume to view the broken transcript read-only for context, but don't continue it.
Suggested fixes
- Don't attach
cache_controlto a text block whose text is empty after image preprocessing - Strip empty text content blocks before sending to
/v1/messages - On detecting this specific 400, surface an in-Claude-Code recovery affordance (e.g., rewrite or drop the offending turn before retrying)
Environment
- Claude Code CLI (Windows)
- OS: Windows 11
- Shell: PowerShell
- Model:
claude-opus-4-7 - Permission mode: auto
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗