#9598: fix(agents): check base64 string length against 5MB API limit
agents
stale
Fixes #5344
## Problem
The Anthropic Messages API enforces the 5MB limit on **base64 string length**, not decoded buffer size. Base64 encoding inflates data by ~33%, so:
- 3.75MB decoded → ~5MB base64 ✅ passes current check
- But gets **rejected by API** with "image exceeds 5 MB maximum"
- Once in session history, **all subsequent messages fail** (even plain text)
## Root Cause
`resizeImageBase64IfNeeded` compared:
- `buf.byteLength` (decoded bytes) against `maxBytes`
- Should compare `params.base64.length` (actual API payload size)
## Changes
1. **Line 73**: Check `params.base64.length` instead of `buf.byteLength`
2. **Line 111-127**: Convert to base64 before size check in resize loop
3. **Line 132**: Use base64 length in error message for accurate reporting
4. **Logs**: Updated to show base64 lengths for better debugging
## Impact
- Prevents API rejections from oversized images
- Stops session corruption (oversized images in history)
- More accurate size tracking throughout resize pipeline
## Testing
Manually verified:
- 3MB file (4.5MB decoded, ~6MB base64) now triggers resize
- Resized output stays under 5MB base64
- Logs show accurate base64 lengths
## Who This Helps
- Slack/Telegram/WhatsApp users sending photos (3-5MB range)
- Anyone with images in session history causing persistent failures
- Reduces "silent failure" cases in production sessions
---
**Ready for review.** Small, focused fix with clear test path.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates image sanitization/resizing to enforce Anthropic’s 5MB limit using the base64 *string length* (the actual payload size) rather than the decoded buffer byte length.
In `src/agents/tool-images.ts`, the initial “over limit” check is switched to `params.base64.length`, and the resize loop now converts each candidate JPEG output to base64 before evaluating whether it fits under `maxBytes`. Logging and the final error message are updated to report base64 sizes for more accurate debugging when images are rejected by the API.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk.
- Change is narrowly scoped to size accounting in the image resize pipeline, keeps existing behavior otherwise, and updates logging/error reporting to match the new limit metric. I did not find any introduced correctness or type/runtime issues in the modified code path.
- No files require special attention
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#23662: fix: cache sanitized images to avoid redundant re-processing per turn
by davidemanuelDEV · 2026-02-22
82.8%
#18219: fix: validate base64 image data before sending to LLM APIs
by Grynn · 2026-02-16
82.1%
#23639: fix(agents): stop re-resizing session history images on every turn ...
by yinghaosang · 2026-02-22
81.9%
#2958: fix(media): wire tools.media.image.maxBytes config to image processin…
by shamsulalam1114 · 2026-01-27
81.9%
#23706: perf: cache image resize results to avoid redundant processing (#23...
by echoVic · 2026-02-22
79.7%
#20913: fix: intercept Discord embed images to enforce mediaMaxMb
by MumuTW · 2026-02-19
78.7%
#16018: feat: add image support to /v1/chat/completions endpoint
by sebastienb · 2026-02-14
77.6%
#6805: fix: increase WebSocket MAX_PAYLOAD_BYTES to 6MB for attachments
by cortexuvula · 2026-02-02
77.3%
#8172: fix(sessions_list): strip base64 image data to prevent context over...
by Flamrru · 2026-02-03
77.2%
#19135: fix(agents): prune excess images from conversation history (#19099)
by pierreeurope · 2026-02-17
76.6%