[BUG] Read: Haiku 4.5 returns screenshot coordinates ~0.76x too small; the API shrinks the image again and the scale note doesn't cover it

Status Open
Reported on v2.1.294
Maintainer reply None cached
Activity 0 comments · opened Oct 8, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When Haiku 4.5 reads a screenshot through the Read tool and is asked where something is, it answers in the coordinates of a smaller image than Claude Code says it sent. Every point comes back at about 0.76x on a 1920x1080 image and about 0.73x on a 2560x1440 one. Sonnet 5.5 answers in the image's own pixels on the same images, and Haiku is also exact on a 1280x720 image.

This is what Read tells the model, from --output-format stream-json:

  • 1920x1080: displayWidth: 1920, displayHeight: 1080, with no scale note. Claude Code treats it as sent 1:1.
  • 2560x1440: displayWidth: 2000, displayHeight: 1125, plus [Image: original 2560x1440, displayed at 2000x1125. Multiply coordinates by 1.28 to map to original image.]

Haiku's answers fit an image about 1456 px wide in both cases:

  • 1920x1080: 1456 / 1920 = 0.758. Haiku measured 0.762 in x and 0.756 in y.
  • 2560x1440: 1456 / 2000 x 1.28 = 0.728. Haiku measured 0.731 and 0.729. It does apply the 1.28 note, but to coordinates that were already 0.728x too small.

This matches the vision docs:

  • Haiku 4.5 is on the Standard resolution tier: a 1568 px long edge and 1568 visual tokens. The docs' own table lists 1920x1080 → 1456x819.
  • Claude 4.7 and later models are on the High-resolution tier, up to 2576 px. That's why Sonnet 5.5 isn't affected.
  • The docs say Claude returns pixel coordinates "relative to the image it sees after resizing".

Read's 2000 px cap and its "multiply by" note assume the high-resolution tier. For a Standard-tier model, the API shrinks the image a second time. Haiku answers in that smaller image's pixels, and Read's note doesn't account for the second resize.

The result is that a Haiku subagent doing anything click-shaped (computer use, GUI testing, "where is X in this screenshot") misses by hundreds of pixels on any screenshot over the Standard-tier limit. That includes every 1080p screen. The same should apply to every other Standard-tier model selectable in Claude Code. We only tested Haiku 4.5.

What Should Happen?

The coordinates Haiku gives should map back to the original image, the same way they already do for Sonnet and Opus. Either of these would do it:

  1. Resize to the model's own tier. For a Standard-tier model, Read resizes with the API's rule (1568 px long edge, 1568 visual tokens; the docs give a reference implementation) and puts the matching scale in its note. For example: original 1920x1080, displayed at 1456x819. Multiply coordinates by 1.3187. The image then reaches the model unchanged, and the existing note covers the rest. In our tests Haiku is accurate on images under the limit (see Additional Information).
  2. At least tell the model. Put the size the model will actually see in the note, not the size Claude Code sent.

The docs' "oversized_image": "error" option would also expose the mismatch as an error instead of a silent second resize.

Error Messages/Logs

No error. Haiku's answers vs the truth (dots drawn at known centres; dot radius 16-21 px):

model              image       x-ratio  y-ratio  median off  max off  on the dot
haiku-4-5-20251001 1280x720     1.005    0.995      3.2 px     7.6 px     8/8
haiku-4-5-20251001 1920x1080    0.762    0.756    268.8 px   471.8 px     0/8
haiku-4-5-20251001 2560x1440    0.731    0.729    405.2 px   694.3 px     0/8
sonnet-5-5         1280x720     1.000    1.000      0.0 px     0.0 px     8/8
sonnet-5-5         1920x1080    1.000    1.000      0.0 px     1.0 px     8/8
sonnet-5-5         2560x1440    1.000    1.001      1.0 px     1.0 px     8/8

Haiku, 1920x1080 (truth in brackets):
A 150,95 (192,130)   B 1235,120 (1632,162)   C 730,410 (960,540)    D 300,655 (384,864)
E 1320,735 (1728,972) F 510,245 (672,324)    G 1020,535 (1344,702)  H 880,80 (1152,108)

Steps to Reproduce

  1. Save this script as make_targets.py. It needs Pillow. It draws eight labelled red dots at known positions and writes the true centres next to the image:

``python
# Usage: python3 make_targets.py 1920 1080 out.png
import sys, json
from PIL import Image, ImageDraw, ImageFont
W, H, out = int(sys.argv[1]), int(sys.argv[2]), sys.argv[3]
fracs = {"A": (0.10, 0.12), "B": (0.85, 0.15), "C": (0.50, 0.50), "D": (0.20, 0.80),
"E": (0.90, 0.90), "F": (0.35, 0.30), "G": (0.70, 0.65), "H": (0.60, 0.10)}
img = Image.new("RGB", (W, H), "white")
d = ImageDraw.Draw(img)
r = max(14, W // 120)
font = ImageFont.load_default(size=r * 2)
truth = {}
for k, (fx, fy) in fracs.items():
x, y = round(fx * W), round(fy * H)
truth[k] = [x, y]
d.ellipse([x - r, y - r, x + r, y + r], fill="red")
d.text((x + r + 6, y), k, fill="black", font=font, anchor="lm")
img.save(out)
json.dump(truth, open(out + ".truth.json", "w"))
print(out, truth)
``

  1. Make the images:

``bash
python3 make_targets.py 1920 1080 targets-1920x1080.png
python3 make_targets.py 2560 1440 targets-2560x1440.png
python3 make_targets.py 1280 720 targets-1280x720.png
``

  1. Ask Haiku for the dots' centres, once per image:

``bash
img=$PWD/targets-1920x1080.png
claude -p "Read the image $img with the Read tool. It has red dots labelled A to H. For each dot, give the pixel coordinates of its centre in the image's own pixels (x from the left edge, y from the top). Reply with only a JSON object like {\"A\":[x,y],...}, nothing else." \
--model claude-haiku-4-5-20251001 --allowedTools Read --output-format stream-json --verbose < /dev/null
``

  1. Compare the answer with targets-1920x1080.png.truth.json. Every coordinate comes back at about 0.76x the truth. On the 2560x1440 image it's about 0.73x, and on 1280x720 it's correct.
  2. Run the same command with --model claude-sonnet-5-5. It's correct on all three images.

Claude Model

Other

Haiku 4.5 (claude-haiku-4-5-20251001). Sonnet 5.5 was the control.

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.294 (Claude Code)

Platform

Anthropic API

Operating System

Other Linux

Terminal/Shell

Non-interactive/CI environment

Additional Information

We first hit this with real desktop screenshots, not the synthetic dots above: 12 screenshots (1920x1080, 2560x1440 and 3840x2160) with 112 hand-checked click targets (launcher entries, toolbar icons, toggles, table cells), all answered through Read on 2.1.292.

| Haiku 4.5, condition | Targets hit |
|---|---|
| Full-size screenshot | 0/112 (median 347 px off; predicted/true = 0.758 in x and y) |
| Same, with a pixel ruler labelled in screen pixels drawn on the image | 2% (Haiku ignores the labels) |
| Screenshot scaled to 1280 wide first, answer in its pixels | 62% |
| Screenshot scaled to 1456x819 first | 67% (95-97% on large targets) |

Opus 5.5 and Sonnet 5.5 hit 100% and 99% of the same 112 targets on the full-size screenshots, so the targets aren't the problem. Once the image is under the API limit, Haiku's remaining misses are small targets, which is a model-skill question rather than this bug.

View original on GitHub ↗