[BUG] Oversized but valid screenshots crash agent sessions with 'Could not process image' — propose client-side resize + graceful in-context removal

Resolved 💬 3 comments Opened May 14, 2026 by jphein Closed May 18, 2026

Preflight Checklist

  • [x] I have searched existing issues — found #47976 (mislabeled .png → session corruption) and #55767 (auto-generated PNGs rejected); this is a related-but-distinct third pattern that bridges them
  • [x] This is a single bug report
  • [x] I am using the latest Claude Code version involved in the failure (multi-agent session on 2.1.141, 2026-05-14)

What's Wrong?

Oversized but valid PNG screenshots — captured by an agent via adb shell screencap + adb pull, written to ~/.claude/projects/<project>/scratch/, then loaded into context via Read or context-restore — get rejected by the multimodal API with 400 "Could not process image", and the agent's whole task crashes ungracefully. Partial work is lost; the agent's tool_uses counter continues but its output is replaced by the error message and no recovery happens.

Surface details (concrete repro from our session):

  • Agent grabs Android screenshot via adb -s <device> shell screencap -p /sdcard/x.png && adb -s <device> pull /sdcard/x.png ~/.claude/projects/.../scratch/qa/x.png. Result: a valid PNG, 1080×2640 px, ~250 KB.
  • Agent writes ~7 such files over several QA journeys.
  • At some point during the multi-step task (likely a Read-back of one of the files, or context-restore in a multi-agent flow), the multimodal API rejects the message containing the image content block with:

``
API Error: 400 Could not process image
``

  • The agent task terminates. Its scratch journal up to that point is preserved, but the final summary block is replaced by the API error; the rest of the planned work is silently dropped. From the orchestrator's perspective, the agent "completed" but with an error string as its result.

This is a third pattern adjacent to:

  • #47976 — mislabeled .png (JSON-in-png-file) → session corruption. Same recovery failure (poisoned context); different upstream cause (input validation).
  • #55767 — Claude-Code auto-captured PNGs rejected by API. Same API error; different upstream cause (the auto-capture path produces images that hit a different limit).

Our case (#X, this issue): a real, valid PNG file with mainstream Android dimensions and a reasonable byte size still trips the multimodal API's image processor, and Claude Code has no client-side guard against it. The fix is preventive + restorative.

Steps to Reproduce

  1. Have an agent grab a fullscreen Android screenshot via adb shell screencap -p /sdcard/x.png && adb pull /sdcard/x.png ~/.claude/projects/<project>/scratch/x.png (any flagship phone or tablet — 1080-1440 px wide, 2400-3200 px tall, 200 KB-2 MB).
  2. In the same agent or a follow-up agent, do any operation that brings the file into model context: Read on the path, restart with the path in a recent tool_result, or a context-summarization step that re-loads scratch files.
  3. The API returns 400 Could not process image. The agent's tool_use count keeps incrementing but the final result is the error string. Partial work is lost.

I haven't been able to pin down the exact limit that triggers it (it's not megabyte-aware on the public docs side and the error message doesn't carry a size hint), but empirically:

  • 1080×2640 / 228 KB → fails
  • 800×1340 / 72 KB → passes
  • 853×1280 / 28 KB (downscaled to JPEG q=80) → passes

So the trigger appears to be either a long-edge cap (around 1280 px?) or a byte-size cap (around 150 KB?), or a PNG-decoder edge case.

Expected Behavior

Two clean fixes, both implementable independently:

  1. Client-side pre-flight validation/resize. Before Claude Code sends an image content block to the API, check its dimensions and byte size against the API's documented limits (or empirically-determined caps if undocumented). If it exceeds, transparently downscale via the host's image library (ImageMagick / Skia / etc.) to a known-safe envelope (e.g., max 1280px long edge, JPEG q=80) and send the downscaled version. The agent's Read path can keep showing the original; only the API-bound copy needs to be small.
  1. Graceful in-context removal on API 400. When the API returns Could not process image, drop that specific image content block from the conversation history and retry without it (or skip past that turn's image input entirely), instead of letting the bad block poison every subsequent turn / kill the agent task. This is the same fix #47976 already proposes as their item (3); reinforcing here with a different upstream cause.

Either fix alone would have prevented our agent crash. Both together would make Claude Code's image-handling path actually reliable for the agent-driven screenshot-grabbing workflows that QA / mobile-app-dev / browser-automation users routinely run.

Actual Behavior

Agent task terminates. Whatever scratch journal / partial output existed before the failing turn survives; everything after is lost. The orchestrator agent sees a completed status but the result field carries the API error verbatim — there's no signal that this was a "we couldn't process the image" failure vs. a "the agent's task is done" outcome.

Workaround (for other users hitting this today)

We deployed a global PostToolUse Bash hook that auto-compresses fresh PNGs in ~/.claude/projects/ scratch dirs to JPEG q=80, max 1280 px on the long edge, while keeping the .png filename so existing scratch journal paths still resolve. The hook lives at ~/.claude/hooks/screenshot-compress.sh and is registered in ~/.claude/settings.json under hooks.PostToolUse[].matcher=Bash. It fires after every Bash invocation, scans for PNGs with mtime < 60s, and skips images already under 150 KB / 1280 px. ImageMagick convert ... -resize "1280x1280>" -quality 80 -strip jpeg:<path> does the work.

Verified end-to-end: 10 MB / 2000×3000 PNG → 126 KB / 853×1280 JPEG (passes), small images correctly left alone. Hook source on request.

This is a workaround, not a fix — the real fix is in Claude Code's outbound-image path. But it unblocks QA workflows today.

Related

  • #47976 — Read on mislabeled .png causes unrecoverable session corruption (same recovery failure, different upstream cause)
  • #55767 — Auto-generated PNGs rejected with image/png not supported (same API error surface, different image origin)

Claude Code Version

2.1.141 (Opus 4.7, 1M context)

Platform / OS

Linux 6.17.0-20-generic (Ubuntu desktop), bash, terminal CLI mode (not the IDE extension or the web app)

Severity

High for multi-agent / agent-orchestration workflows where one bad image crashes the whole task and silently loses 30+ minutes of work. Lower for single-conversation use where the user can /rewind to recover.

View original on GitHub ↗

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