claude-code - 💡(How to fix) Fix Image-only message sends empty text block with cache_control, 400s and kills conversation

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

The Claude Code desktop client sends an empty text content block (with cache_control attached) when a user submits a message containing only an image attachment and no typed text. The Messages API rejects with 400, and the conversation in the desktop app becomes unrecoverable. Has occurred repeatedly in normal use (paste image, hit send before typing).

Error Message

  • API Error: 400 messages: text content blocks must be non-empty
  • API Error: 400 messages.112.content.1.text: cache_control cannot be set for empty text blocks
  • API Error: 400 messages.76.content.1.text: cache_control cannot be set for empty text blocks

Root Cause

Root cause (apparent)

The serializer for outgoing messages appends an empty text block to content and marks it with cache_control: { type: "ephemeral" }. Both properties independently violate the Messages API contract:

  • A text block with empty string is invalid.
  • cache_control cannot be applied to an empty/whitespace text block.

Fix Action

Workaround

Type any single character before sending. Reliable but easy to forget.

RAW_BUFFERClick to expand / collapse

Summary

The Claude Code desktop client sends an empty text content block (with cache_control attached) when a user submits a message containing only an image attachment and no typed text. The Messages API rejects with 400, and the conversation in the desktop app becomes unrecoverable. Has occurred repeatedly in normal use (paste image, hit send before typing).

Exact errors observed

  • API Error: 400 messages: text content blocks must be non-empty
  • API Error: 400 messages.112.content.1.text: cache_control cannot be set for empty text blocks
  • API Error: 400 messages.76.content.1.text: cache_control cannot be set for empty text blocks

The indices (112, 76) indicate this happens deep into long sessions — making the lost context especially costly.

Repro

  1. Start a remote-control daemon (claude remote-control --name foo --permission-mode auto) and pair from the desktop client.
  2. Attach an image to the prompt (paste/drag-drop).
  3. Send WITHOUT typing any text.
  4. API returns 400; conversation becomes inert. Daemon (control + worker) stays alive; only the app-side thread is dead.

Root cause (apparent)

The serializer for outgoing messages appends an empty text block to content and marks it with cache_control: { type: "ephemeral" }. Both properties independently violate the Messages API contract:

  • A text block with empty string is invalid.
  • cache_control cannot be applied to an empty/whitespace text block.

Suggested fix

Before sending, strip any text blocks whose .text is empty/whitespace. If a trailing cache breakpoint is desired, attach cache_control to the last non-empty block (the image block, or the prior text block) instead of synthesizing an empty one.

Workaround

Type any single character before sending. Reliable but easy to forget.

Impact

  • Loss of in-flight conversation context (JSONL backups exist but the live session can't resume).
  • Daemon survives, so it's not a crash — purely a serialization bug at the client/API boundary.

Environment

  • Claude Code CLI: 2.1.143
  • Node: v24.15.0
  • OS: Linux 6.17.0-29-generic (Ubuntu)
  • Mode: remote-control daemon (claude remote-control --name <X> --permission-mode auto)
  • Client: Claude desktop (Linux)

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING