claude-code - 💡(How to fix) Fix [FEATURE] Persist oversized-image strip so synthetic placeholder is not re-emitted every turn

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…

Error Message

"type":"assistant","model":"<synthetic>", "content":[{"type":"text","text":"API Error: an image in the conversation could not be processed and was removed. Re-read the file with a different approach if you still need it."}], "error":"invalid_request", "errorDetails":"400 {"type":"error","error":{"type":"invalid_request_error","message":"messages.34.content.1.image.source.base64.data: At least one of the image dimensions exceed max allowed size for many-image requests: 2000 pixels"},"request_id":"req_exampleABC123"}", "isApiErrorMessage":true

Root Cause

  • #42256 — "Read tool sends oversized images to API, then re-sends them on every subsequent message." Same underlying root cause (oversized images persist in history), filed before the 2.1.121/2.1.126 recovery landed. That issue's worst symptom — the session is unusable — has been addressed. This issue is the residual: the recovery itself replays. Happy to close in favor of #42256 if maintainers prefer; flagging here so the dup-detection bot has context.
  • #34566, #56934 — related but distinct (session crashes / no recovery). The new fixes address those; mine is downstream.

Code Example

- Claude Code Version: 2.1.143
- Platform: Max subscription
- Operating System: macOS 26.4.1 (Apple M2 Ultra, 128 GB)
- VS Code: 1.120.0
- VS Code extension: anthropic.claude-code@2.1.143
- Terminal/Shell: VS Code integrated webview (zsh)

---

"type":"assistant","model":"<synthetic>",
"content":[{"type":"text","text":"API Error: an image in the conversation could not be processed and was removed. Re-read the file with a different approach if you still need it."}],
"error":"invalid_request",
"errorDetails":"400 {\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"messages.34.content.1.image.source.base64.data: At least one of the image dimensions exceed max allowed size for many-image requests: 2000 pixels\"},\"request_id\":\"req_exampleABC123\"}",
"isApiErrorMessage":true
RAW_BUFFERClick to expand / collapse

Preflight

  • I searched existing issues and didn't find an exact duplicate (closest: #42256, see below)
  • This is a single feature request

Problem Statement

The image-recovery work that landed in 2.1.121 (failed image blocks degrade to a text placeholder instead of crashing the session) and 2.1.126 (oversized images in history are stripped and the request retried) is genuinely great — sessions that used to be permanently bricked now keep going.

What is still rough: the recovery does not persist. Every subsequent turn re-encounters the same oversized image at the same position in history, re-strips it, and re-emits the synthetic placeholder assistant turn:

API Error: an image in the conversation could not be processed and was removed. Re-read the file with a different approach if you still need it.

In a single real session at 2.1.143 I observed 48 emissions of that exact placeholder, each one a separate synthetic assistant message in the transcript, each tied to a fresh req_011... ID and a 400 from messages.34.content.1.image.source.base64.data. They all reference the same offending image at the same position — the strip is per-turn, not per-session.

Cost: each emission is a redundant 400 round-trip, plus a synthetic message that takes up a turn slot and burns cache (the model sees a noisier history). In a long session it crowds real context out and confuses downstream tools that scan transcripts.

Proposed Solution

After the first successful strip-and-retry, persist the stripped state to the session transcript so the offending image is gone for the rest of the session. Subsequent turns should not re-trigger the 400 or re-emit the placeholder.

Two reasonable shapes:

  1. Mutate history in place. After a strip-and-retry succeeds, rewrite the original message at that position to remove the image block (or replace it with the text placeholder), so the next turn sends clean history.
  2. Collapse into a single marker. Keep the original message intact but mark the image block as "known bad, do not re-send" in session state, and emit a single (prior image removed from context) system note on the first occurrence. Subsequent turns skip the block silently.

Either shape would have prevented 47 of the 48 emissions in my session.

Alternative Solutions

  • /clear — works, but loses all session context. Not acceptable for long-running work.
  • Manually editing the JSONL transcript on disk — possible (isApiErrorMessage: true and model: "<synthetic>" are easy to grep for), but fragile and not something a normal user would do.
  • Running /compact — drops the offending message along with everything else, same downside as /clear.

Priority

Medium. The 2.1.121/2.1.126 work already prevents the worst outcome (session death). This is a quality-of-life follow-on, not a blocker.

Feature Category

Performance (token / round-trip waste) and Core (session state persistence).

Use Case Example

  1. Long-running session, hours of context built up.
  2. User pastes a 3000×4000 screenshot for diff review.
  3. API returns 400 — image exceeds 2000px on a dimension.
  4. Harness strips it, retries successfully, session continues. Great.
  5. Every subsequent user turn: same image still at position 34 of history. Same 400. Same synthetic placeholder appended.
  6. After 50 turns of normal work, the transcript has 50 copies of the placeholder, the model has been hit with 50 redundant 400s, and the user has no idea why their session feels noisier than it should.

Related Issues

  • #42256 — "Read tool sends oversized images to API, then re-sends them on every subsequent message." Same underlying root cause (oversized images persist in history), filed before the 2.1.121/2.1.126 recovery landed. That issue's worst symptom — the session is unusable — has been addressed. This issue is the residual: the recovery itself replays. Happy to close in favor of #42256 if maintainers prefer; flagging here so the dup-detection bot has context.
  • #34566, #56934 — related but distinct (session crashes / no recovery). The new fixes address those; mine is downstream.

Environment

- Claude Code Version: 2.1.143
- Platform: Max subscription
- Operating System: macOS 26.4.1 (Apple M2 Ultra, 128 GB)
- VS Code: 1.120.0
- VS Code extension: [email protected]
- Terminal/Shell: VS Code integrated webview (zsh)

Additional Context

Sample sanitized log lines from the offending transcript (one session, 48 emissions, all with the same upstream error):

"type":"assistant","model":"<synthetic>",
"content":[{"type":"text","text":"API Error: an image in the conversation could not be processed and was removed. Re-read the file with a different approach if you still need it."}],
"error":"invalid_request",
"errorDetails":"400 {\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"messages.34.content.1.image.source.base64.data: At least one of the image dimensions exceed max allowed size for many-image requests: 2000 pixels\"},\"request_id\":\"req_exampleABC123\"}",
"isApiErrorMessage":true

messages.34.content.1.image is the same position across all 48 emissions, which is what makes the per-turn re-strip obvious.

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 [FEATURE] Persist oversized-image strip so synthetic placeholder is not re-emitted every turn