claude-code - 💡(How to fix) Fix API 400 "cache_control cannot be set for empty text blocks" when user message contains only an image

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…

When a user sends a message containing only an image (no text), the client serializes the message content as [image_block, empty_text_block]. On the next API call, the prompt-caching logic attaches cache_control: ephemeral to the last content block — which is the empty text block. Anthropic API rejects this with 400 invalid_request_error: cache_control cannot be set for empty text blocks, and the session becomes permanently stuck: every subsequent turn replays the broken message and 400s again.

Error Message

Actual Error

"type": "error", "error": {

Root Cause

When a user sends a message containing only an image (no text), the client serializes the message content as [image_block, empty_text_block]. On the next API call, the prompt-caching logic attaches cache_control: ephemeral to the last content block — which is the empty text block. Anthropic API rejects this with 400 invalid_request_error: cache_control cannot be set for empty text blocks, and the session becomes permanently stuck: every subsequent turn replays the broken message and 400s again.

Fix Action

Workaround

User-side: always include at least one non-empty character when sending an image-only message.

Recovery for an already-broken session: kill the daemon (or close the app), edit the session jsonl to drop the empty text block from the offending message (or replace "text": "" with "text": "."), restart.

Code Example

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "messages.60.content.1.text: cache_control cannot be set for empty text blocks"
  },
  "request_id": "req_011Cb5dtKrgn5pejV1M7Thyi"
}

---

{
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "..."}},
      {"type": "text", "text": ""}
    ]
  }
}
RAW_BUFFERClick to expand / collapse

Summary

When a user sends a message containing only an image (no text), the client serializes the message content as [image_block, empty_text_block]. On the next API call, the prompt-caching logic attaches cache_control: ephemeral to the last content block — which is the empty text block. Anthropic API rejects this with 400 invalid_request_error: cache_control cannot be set for empty text blocks, and the session becomes permanently stuck: every subsequent turn replays the broken message and 400s again.

Environment

  • Claude Code version: 2.1.118 (reproduced); likely same on later versions, no fix in changelog
  • Entry point: sdk-cli (via claude remote-control background daemon on Linux). I expect the bug is in the message serialization layer and reproduces from the desktop app too
  • Platform: Linux x86_64, Node v22.22.2
  • Model: claude-opus-4-7 (1M context, Max plan)

Reproduction Steps

  1. Open any session
  2. Paste / drag an image into the input
  3. Do not type anything else — press Enter immediately
  4. Wait for the model reply (succeeds)
  5. Send any next message
  6. → API call fails with 400 messages.N.content.M.text: cache_control cannot be set for empty text blocks
  7. → Session is now permanently broken; every turn replays the bad message

Expected Behavior

Either:

  • Client should not write an empty text block when the user message contains only an image, or
  • Prompt-caching layer should skip empty text blocks when choosing where to attach cache_control

Actual Error

{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "messages.60.content.1.text: cache_control cannot be set for empty text blocks"
  },
  "request_id": "req_011Cb5dtKrgn5pejV1M7Thyi"
}

Reproduction Evidence

The offending message in the session jsonl:

{
  "type": "user",
  "message": {
    "role": "user",
    "content": [
      {"type": "image", "source": {"type": "base64", "media_type": "image/png", "data": "..."}},
      {"type": "text", "text": ""}
    ]
  }
}

The empty text block is the smoking gun.

Workaround

User-side: always include at least one non-empty character when sending an image-only message.

Recovery for an already-broken session: kill the daemon (or close the app), edit the session jsonl to drop the empty text block from the offending message (or replace "text": "" with "text": "."), restart.

Suggested Fix

In client-side content normalization, filter blocks where type === "text" && (text ?? "").length === 0 before sending. The same filter would protect against future variants of this bug (e.g. user clears text after attaching an image)

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

claude-code - 💡(How to fix) Fix API 400 "cache_control cannot be set for empty text blocks" when user message contains only an image