Accumulated inline image base64 in session history causes 'Request too large (max 20MB)' — blocks all messages including /feedback

Open 💬 15 comments Opened Apr 3, 2026 by nikkundra

Bug Description

Getting \Request too large (max 20MB). Double press esc to go back and try with a smaller file.\ error on text-only follow-up messages after prior inline screenshots have accumulated in the conversation history. The error also blocks submitting \/feedback\, making it difficult to report the issue when it occurs.

Suspected regression, reproduced on v2.1.91. The error was not observed between 2026-03-07 and 2026-04-03 across dozens of sessions on this machine. Historical search across all local Claude Code sessions shows only 3 affected sessions: one on 2026-03-07 and two on 2026-04-03. Note: absence from the changelog between v2.1.73–v2.1.91 does not prove no regression shipped — it only means none was documented.

Probable Root Cause (Session Forensics — Not Confirmed by Anthropic)

Inline image blocks (pasted/attached screenshots) are persisted as base64 in conversation history and re-sent with every subsequent API call. Once enough images accumulate, the serialized request exceeds the 20MB per-request cap — then every future message fails, even pure text ones with zero images.

Key forensic evidence (from independent Codex CLI audit of the affected session JSONL):

  • First \Request too large\ error occurred at JSONL line 356
  • First screenshot \Read\ call did not occur until JSONL line 390 — the \Read\ tool was NOT the initial trigger
  • At first failure: 14 inline image blocks with ~35.8M base64 characters already in history
  • Total session: 25 inline image blocks with ~55.2M base64 characters
  • Local image cache: 31 files totaling 52.6MB

Additional behavioral observations:

  • Even after \/rewind\, the base64 from previously-sent images persists in conversation state — text-only prompts still carry the accumulated image payload
  • Initially, providing file paths (which triggers the \Read\ tool) caused the error, while providing file URLs did not — but eventually even URLs stopped working
  • The error compounds: each \/rewind\ gives temporary relief but the underlying payload remains
  • The user was on a 1M-context model (Opus 4.6) at only 41% utilization (~409K tokens) — the 20MB wire-size cap is hit long before the semantic token limit

Prior Image-Related Fixes (Release Notes)

| Version | Release Date | Change |
|---------|-------------|--------|
| v1.0.28 | Pre-2026 | "Resizes images before upload to prevent API size limit errors" |
| v2.1.37 | Feb 7, 2026 | "Stripping images before sending to the compaction API" (#26188) |
| v2.1.43 | ~Feb 2026 | "Fixed image dimension limit errors to suggest /compact" |
| v2.1.71 | Mar 7, 2026 | "Fixed the Read tool putting oversized images into context when image processing failed" |
| v2.1.72 | Mar 10, 2026 | "Fixed oversized and truncated images from Bash data-URL output" |

The v2.1.71/v2.1.72 fixes addressed specific edge cases (Read tool failure path + Bash data-URL), but did not implement a general 20MB pre-flight payload size check or image pruning from accumulated conversation history.

Steps to Reproduce

  1. Start a Claude Code session (v2.1.91, Opus 4.6 1M context, Max subscription 20x)
  2. Paste or attach several screenshots/images during the conversation (inline, not necessarily via \Read\ tool)
  3. Continue working — the base64 of each image persists in conversation history
  4. After enough images accumulate (~14+ Retina screenshots = ~35MB base64), the serialized request exceeds 20MB
  5. Every subsequent message — including pure text with no images — fails with \Request too large (max 20MB)\
  6. \/feedback\ was not a reliable escape hatch during the failure state
  7. \/rewind\ gives temporary relief but the error recurs since image data remains in history
  8. Providing file paths (\Read\ tool) vs file URLs behave differently initially, but both eventually fail

Expected Behavior

  • Inline image data should be pruned, cached by reference, or excluded from re-serialization after initial processing
  • If re-sending is necessary, auto-compact should trigger before the 20MB cap
  • The error message should say "conversation payload too large" not "try with a smaller file"
  • \/feedback\ should always work regardless of conversation size
  • A 1M-context model should not hit a 20MB serialization wall at 41% token utilization

Session Evidence

| Date | Session | Role | Notes |
|------|---------|------|-------|
| 2026-03-07 | ec29e14c | Affected | First observed occurrence (14 error instances in JSONL) |
| 2026-03-08 to 2026-04-02 | (none) | — | ~4 weeks with no occurrences across many sessions |
| 2026-04-03 | 0d396357 | Primary affected session | 28 error instances, 14 inline images before first failure, 25 total |
| 2026-04-03 | 8a545e48 | Follow-up investigation | Session used to file this issue and research the bug (not independent repro) |

Environment

  • Claude Code: v2.1.91 (released Apr 2, 2026)
  • Subscription: Claude Max (20x)
  • Model: Opus 4.6 (1M context window)
  • macOS: Darwin 25.4.0
  • Context at failure: ~409,588 tokens (41% of 1M window)
  • Session: ~197 user turns, ~201 assistant messages

Related Issues (Same Root Cause)

  • #42256 — Read tool re-sends oversized images on EVERY subsequent message (OPEN)
  • #37418 — MCP screenshot makes session permanently unusable (OPEN)
  • #34751 — 99KB PNG triggers 20MB error; confirmed regression (OPEN)
  • #30542 — Best root-cause writeup; accumulated image data permanently kills conversations (CLOSED by stale bot, NOT fixed)
  • #38496 — Confirmed regression from v2.1.80 to v2.1.81 (CLOSED as duplicate)

Suggested Fixes

  1. Stop persisting base64 blobs in full — prune inline image data from conversation history after initial processing, or use a content reference/cache
  2. Add a pre-flight size check — before dispatching the API request, check serialized size and auto-compact or strip images if approaching 20MB
  3. Fix the error message — "conversation payload too large" not "try with a smaller file"
  4. Exempt \/feedback\ — truncate context before sending feedback so the reporting mechanism always works
  5. Show a warning at 80% of the cap — let users \/compact\ proactively before hitting the hard wall
  6. Differentiate file path (\Read\ tool) vs URL behavior — both should be handled consistently

View original on GitHub ↗

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