Repository navigation
fix(session): sanitize image attachments before sending to API - #19555
kozak-codes wants to merge 2 commits into
Conversation
Prevents sessions from getting stuck replaying image attachments that exceed provider limits. Three new guards added to unsupportedParts(): - Unsupported MIME type: only image/jpeg, image/png, image/gif, image/webp are accepted (all major providers). image/jpg is normalized to image/jpeg. Anything else (bmp, tiff, svg, etc.) is replaced with a descriptive error. - Size limit: base64 payload > 5 MB is rejected. Anthropic enforces a hard 5 MB cap; exceeding it poisons the session history and causes every subsequent request to fail with a 400. - Dimension limit: PNG images with any side > 2000px are rejected. Anthropic rejects these in multi-image requests with a 400. Dimensions are read from the PNG IHDR header without a full decode (fast, no deps). Adds 6 new tests covering: unsupported MIME, jpg normalization, oversized payload, oversized PNG dimensions, valid small PNG, all four accepted types. Closes: anomalyco#4781 Related: anomalyco#9785, anomalyco#9512, BASIC-BIT#1
|
Thanks for updating your PR! It now meets our contributing guidelines. 👍 |
|
Bump |
|
I've been tracking the session-bricking bug across #4781, #14562, #21668, #12068, and #13865. This PR addresses the core issue cleanly. The approach makes sense: validate images in This doesn't resize images (a user pasting a 6 MB screenshot will see an error instead of it just working), but that's a reasonable follow-up. The critical thing is stopping sessions from becoming permanently unrecoverable, which this does. Multiple people on our team are hitting this bug regularly. Would appreciate a maintainer review. CI is all green. |
|
Automated PR Cleanup Thank you for contributing to opencode. Due to the high volume of PRs from users and AI agents, we periodically close older PRs using automated criteria so maintainers can focus review time on the most active and community-supported contributions. This PR was closed because it matched the following cleanup criteria:
PRs created within the last month are not affected by this cleanup. If you believe this PR was closed incorrectly, or if you are still actively working on it, please leave a comment explaining why it should be reopened. A maintainer can review and reopen it if appropriate. Thanks again for taking the time to contribute. |
Issue for this PR
Closes #4781
Type of change
What does this PR do?
When a tool (like
reador the screenshot tool) returns an image attachment, it gets stored in session history and replayed to the API on every subsequent request. If that image violates provider limits, the session gets permanently stuck — every message fails with the same 400, even if you tell the model to stop using images.Three cases cause this:
image/bmp,image/tiff) — providers only accept jpeg, png, gif, webpThe fix adds these three guards to
unsupportedParts()intransform.ts. Bad images are replaced with a descriptive error string in the context instead of being sent. Also normalizesimage/jpg→image/jpegsince both are valid but only the latter passes the whitelist.PNG dimensions are read from the IHDR header (first 32 bytes via
atob) — no extra dependencies needed.How did you verify your code works?
Hit both the 5 MB and 2000px errors in real sessions. Fixed them manually via DB surgery, then confirmed the guards here would have caught them before they were stored. Added 6 new unit tests covering all three failure modes plus the jpg normalization and valid-image passthrough cases. All 125 tests pass.
Screenshots / recordings
No UI changes.
Checklist