[BUG] Read tool massively overestimates image token cost, causing unnecessary quality loss on screenshots
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?
The Read tool uses an incorrect token estimation formula for images, causing aggressive unnecessary compression even when the image would comfortably fit within Claude's actual token budget.
When reading an image file, Claude Code estimates the token cost using:
estimatedTokens = Math.ceil(base64.length * 0.125)
This treats base64 characters like text tokens. But the Anthropic API actually counts image tokens as 28×28 pixel patches:
actualTokens = ⌈width / 28⌉ × ⌈height / 28⌉
These two formulas produce wildly different results for the same image.
Any agent that reads image files (screenshots, diagrams, etc.) via the Read tool receives a degraded version. The agent makes decisions based on a heavily downscaled image while believing it has seen the full resolution. Setting a lower CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS to protect against large text files inadvertently causes severe image quality loss.
What Should Happen?
Image token estimation should use the same patch-based formula the API uses:
estimatedTokens = Math.ceil(width / 28) * Math.ceil(height / 28)
This would correctly identify that a 1280×713 screenshot costs ~1,196 tokens and skip compression entirely.
Error Messages/Logs
A 1280×713 screenshot (common browser viewport size):
| Metric | Value |
|---|---|
| Real API token cost | **1,196 tokens** (`ceil(1280/28) × ceil(713/28)`) |
| Claude Code estimated cost | **74,243 tokens** (`593944 × 0.125`) |
| Overestimate factor | **62×** |
Steps to Reproduce
With the default CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS=25000:
- Claude Code sees 74,243 > 25,000 → triggers compression
- Image gets resized from 1280×713 to 960×535
- Actual token cost of the compressed image: ~700 tokens
- The original would have only cost ~1,196 real tokens — well under the 1,568-token model cap
With CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENS=5000:
- Image gets resized all the way down to 320×178
- Actual token cost: ~84 tokens
- No compression was ever needed
- Tested across SDK versions
0.2.87and0.3.177— both affected CLAUDE_CODE_FILE_READ_MAX_OUTPUT_TOKENSvalues tested:5000(default in some setups) and25000(Claude Code default)- Relevant file:
FileReadTool.ts(readImageWithTokenBudget) andimageResizer.ts(compressImageBufferWithTokenLimit)
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
0.3.177
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Terminal.app (macOS)
Additional Information
_No response_