[BUG] Image upload in cloud environment poisons session — all subsequent API calls return 400, /compact cannot recover

Resolved 💬 3 comments Opened May 4, 2026 by ghost Closed Jun 3, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

Uploading an image file to an active Claude Code session produced a malformed assistant turn that cannot be recovered from. Every subsequent message returns HTTP 400 from the messages API. /compact fails with the same error because it replays the poisoned history.

What Should Happen?

Image is attached to the next user turn and the assistant responds normally.

Error Messages/Logs

### Actual behavior
- First post-upload send returns: `400 invalid_request_error — messages.115.content.1.text: cache_control cannot be set for empty text blocks`
- All further sends return: `400 invalid_request_error — messages: text content blocks must be non-empty`
- `/context` works (local, no API call)
- `/compact` fails with the same 400 (sends poisoned history to API)
- Session is permanently wedged

### Request IDs
- `req_011CahytTreECx4LmdC6TyYm`
- `req_011Cahyu89zvaSC7Yv7rRBdG`
- `req_011CahyyHNFX6Wh8fjjDX4S8`
- `req_011Cahz6eHY4rxdvmK2lvpwS` (from failed `/compact`)

Steps to Reproduce

  1. Start a Claude Code session in the desktop app using the cloud environment
  2. Have an active conversation with tool use (in my case, WebSearch/WebFetch discussion)
  3. Attempt to upload an image file to the session
  4. Send any subsequent message

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

Claude Desktop app 1.5354.0

Platform

Anthropic API

Operating System

Windows

Terminal/Shell

Other

Additional Information

Probable root cause (speculation)

The image upload created an assistant message containing an empty text block, and the prompt cache breakpoint was attached to that empty block. Subsequent requests fail validation on either the empty text or the cache_control marker on it. Because the bad turn is now in persistent history, every replay including /compact triggers the same validation error.

Severity

Medium-high. Session-destroying, no in-app recovery, triggered by a normal user action (file upload). Data loss risk if user has not been checkpointing.

Additional context

Conversation was at 125.7k / 1.0M tokens (13%) when the failure occurred, so this is not a context-limit issue.

View original on GitHub ↗

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