claude-code - 💡(How to fix) Fix Read tool returns incorrect image content for PNG files (rendering routed to wrong file / permuted across batch) [3 comments, 2 participants]

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…
GitHub stats
anthropics/claude-code#52716Fetched 2026-04-24 10:41:35
View on GitHub
Comments
3
Participants
2
Timeline
8
Reactions
0
Author
Timeline (top)
labeled ×5commented ×3

When the Read tool is called on a PNG file path, the rendered image content presented to the model does not match the file's pixel data. Across multiple Read calls on the same paths within one session, returned image content flips between mismatched files, indicating the rendering or routing layer serves wrong content. Minimal reproduction with tiny synthetic PNGs (under 1.5 KB each) confirms the bug is not size-dependent, not model-interpretation, and not caused by image content complexity.

Root Cause

  • The model makes confident claims about image content that contradict file pixel data.
  • Claims drift between turns for the same file path.
  • User-facing trust: multimodal chat becomes unreliable.
  • Downstream: if agents act on image content (visual UI testing, OCR-based automation, screenshot-driven workflows), wrong image content produces wrong actions.

Code Example

from PIL import Image, ImageDraw
import os

base = '/tmp/image_repro'  # adjust for platform
os.makedirs(base, exist_ok=True)

img = Image.new('RGB', (100, 100), (255, 0, 0))
img.save(os.path.join(base, 'test1_solid_red_100x100.png'))

img = Image.new('RGB', (100, 100), (255, 255, 255))
img.save(os.path.join(base, 'test2_solid_white_100x100.png'))

img = Image.new('RGB', (100, 100), (0, 0, 255))
img.save(os.path.join(base, 'test3_solid_blue_100x100.png'))

img = Image.new('RGB', (200, 200), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle([0, 0, 200, 100], fill=(0, 255, 0))
img.save(os.path.join(base, 'test4_top_green_bottom_black_200x200.png'))

img = Image.new('RGB', (400, 400), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle([0, 0, 200, 200], fill=(255, 0, 0))
draw.rectangle([200, 0, 400, 200], fill=(0, 255, 0))
draw.rectangle([0, 200, 200, 400], fill=(0, 0, 255))
draw.rectangle([200, 200, 400, 400], fill=(255, 255, 0))
img.save(os.path.join(base, 'test5_4quadrants_400x400.png'))
RAW_BUFFERClick to expand / collapse

Claude Code: Read tool returns wrong image content for PNG paths

Date observed: 2026-04-24 Claude Code version: 2.1.118 (native, win32-x64) Model: claude-opus-4-7 (1M context), via Bedrock auth Severity: Correctness bug in multimodal Read pipeline. The model receives image content that does not match the file's actual pixel data.

Summary

When the Read tool is called on a PNG file path, the rendered image content presented to the model does not match the file's pixel data. Across multiple Read calls on the same paths within one session, returned image content flips between mismatched files, indicating the rendering or routing layer serves wrong content. Minimal reproduction with tiny synthetic PNGs (under 1.5 KB each) confirms the bug is not size-dependent, not model-interpretation, and not caused by image content complexity.

Minimal Reproduction

A script generated 5 test PNGs with known content (via Python and PIL), saved to a local temp directory.

FileSHA-256 (first 16 hex)SizeDimsKnown content
test1_solid_red_100x100.png1dc0ddcbc8ec8770284 B100x100All pixels RGB (255, 0, 0)
test2_solid_white_100x100.png996ada7513a97066286 B100x100All pixels RGB (255, 255, 255)
test3_solid_blue_100x100.png8fd808817157f21a285 B100x100All pixels RGB (0, 0, 255)
test4_top_green_bottom_black_200x200.png7aadb22946d88d1d396 B200x200Top half RGB (0,255,0), bottom half (0,0,0)
test5_4quadrants_400x400.pnge1ffdf127bb1e5e51,403 B400x400Quadrants: TL red, TR green, BL blue, BR yellow

Test 1: batch Read of all 5 files in a single assistant message

Call orderFile sentRendered content received by model
1test1 (red 100x100)white 100x100 (wrong; matches test2's known content)
2test2 (white 100x100)green-top/black-bottom 200x200 (wrong; matches test4)
3test3 (blue 100x100)4 quadrants RGBY 400x400 (wrong; matches test5)
4test4 (green/black 200x200)red 100x100 (wrong; matches test1)
5test5 (quadrants 400x400)blue 100x100 (wrong; matches test3)

Pattern: the 5 returned images are a permutation of the 5 sent images. Same set of contents, different order. Parallel Read results appear to be mis-paired with their calls at the Claude Code/model boundary.

Test 2: sequential Read of one file alone

Calling Read on test1_solid_red_100x100.png once, not batched:

  • Rendered: solid blue 100x100 (wrong; should be red; matches test3's content).

Calling Read on the same test1_solid_red_100x100.png a third time, still alone, seconds later:

  • Rendered: a full-screen browser screenshot at approximately 1920x1080 that had been shared earlier in the session.

The third call returning content from a completely different, previously-seen file indicates the mis-routing is not just intra-batch. It persists across the session's Read history. Prior Read results appear to be cached somewhere and served to later calls with wrong content keys.

Pixel Fingerprint (ground truth from PIL)

For a 1920x1080 screenshot with a white form background:

  • Pixel at (0,0): dark (browser chrome background)
  • Center pixel: pure white RGB (255, 255, 255), form body
  • Edges: dark

For a narrow 1840x189 cropped dark-theme screenshot:

  • All sampled pixels: uniformly dark RGB approximately (25, 26, 27)

The model's rendered image interpretations across multiple turns did not match these fingerprints. Independent verification (opening the files in OS image viewer) matched the fingerprints.

Failure Modes (hypotheses)

One or more of:

  1. Image pipeline caching/routing bug. The Read tool caches rendered images by a key that is not file path plus content hash, and serves stale or misrouted content on repeated calls.
  2. Call/response pairing bug in parallel Read. Results return in a different order from calls and get mis-paired at the tool-response stitching layer.
  3. Image dimensions exceed rendering budget. Larger images are downscaled or cropped and lose distinguishing content (but this does not explain the minimal repro with tiny 100x100 images).
  4. Unknown other.

The minimal repro rules out (3) as sole cause because the test images are well under any plausible rendering budget.

Why this matters

  • The model makes confident claims about image content that contradict file pixel data.
  • Claims drift between turns for the same file path.
  • User-facing trust: multimodal chat becomes unreliable.
  • Downstream: if agents act on image content (visual UI testing, OCR-based automation, screenshot-driven workflows), wrong image content produces wrong actions.

Suggested investigation

  • Instrument the Read-to-model pipeline for PNG files. Log the path, hash, and bytes or encoded form sent to the model for each Read call.
  • Diff across repeated Reads of the same file within one session: does the model receive identical bytes each time, or is a cache serving by wrong key?
  • Repro with the 5 synthetic PNGs above (PIL script included below).
  • Test across different auth paths (Anthropic, Bedrock, Vertex) for the same symptom.

Reproduction Script

from PIL import Image, ImageDraw
import os

base = '/tmp/image_repro'  # adjust for platform
os.makedirs(base, exist_ok=True)

img = Image.new('RGB', (100, 100), (255, 0, 0))
img.save(os.path.join(base, 'test1_solid_red_100x100.png'))

img = Image.new('RGB', (100, 100), (255, 255, 255))
img.save(os.path.join(base, 'test2_solid_white_100x100.png'))

img = Image.new('RGB', (100, 100), (0, 0, 255))
img.save(os.path.join(base, 'test3_solid_blue_100x100.png'))

img = Image.new('RGB', (200, 200), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle([0, 0, 200, 100], fill=(0, 255, 0))
img.save(os.path.join(base, 'test4_top_green_bottom_black_200x200.png'))

img = Image.new('RGB', (400, 400), (0, 0, 0))
draw = ImageDraw.Draw(img)
draw.rectangle([0, 0, 200, 200], fill=(255, 0, 0))
draw.rectangle([200, 0, 400, 200], fill=(0, 255, 0))
draw.rectangle([0, 200, 200, 400], fill=(0, 0, 255))
draw.rectangle([200, 200, 400, 400], fill=(255, 255, 0))
img.save(os.path.join(base, 'test5_4quadrants_400x400.png'))

Then, in Claude Code, call Read on each file path once in a batch. Observe returned content does not match known pixel values.

Environment

  • OS: Windows 11
  • Shell: MSYS2/Git Bash
  • Model: Claude Opus 4.7 (1M context) via AWS Bedrock
  • Claude Code: 2.1.118 (native win32-x64)

Session transcript and synthetic PNG files available on request. Not posting publicly.

extent analysis

TL;DR

The most likely fix involves addressing the image pipeline caching or routing bug in the Read tool, ensuring that each call receives the correct image content based on the file path and content hash.

Guidance

  • Investigate the Read-to-model pipeline: Log the path, hash, and bytes sent to the model for each Read call to identify if the issue lies in the caching mechanism or the pairing of calls and responses.
  • Diff across repeated Reads: Compare the bytes or encoded form sent to the model for repeated calls of the same file within one session to determine if a cache is serving incorrect content.
  • Test with synthetic PNGs: Use the provided reproduction script to generate and test with the 5 synthetic PNGs across different auth paths to isolate the issue.
  • Verify image content: Independently verify the image content using tools like PIL to ensure that the issue is not with the model's interpretation but with the content being sent to the model.

Example

No specific code changes are suggested at this stage, but the reproduction script provided in the issue can be used to generate test images and verify the behavior:

from PIL import Image, ImageDraw
import os

# Generate and save test images
base = '/tmp/image_repro'
os.makedirs(base, exist_ok=True)

# ... (rest of the script remains the same)

Notes

The exact cause of the issue (caching bug, call/response pairing bug, etc.) needs to be determined through further investigation. The provided guidance is aimed at helping to isolate and understand the problem rather than providing a direct fix.

Recommendation

Apply a workaround by disabling any caching mechanisms in the Read tool or ensuring that the cache key includes both the file path and content hash to prevent serving stale or misrouted content. This approach is chosen because the issue seems to be related to how images are cached and served, and addressing this directly could resolve the problem.

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 Read tool returns incorrect image content for PNG files (rendering routed to wrong file / permuted across batch) [3 comments, 2 participants]