anomalyco / anomalyco/opencode

read tool trusts the file extension when magic bytes don't match: a corrupt .png is attached as image/png and bricks the session (400 invalid image data on every request)

Open
#48,476 0 comments 0 reactions 1 assignee View on GitHub

@kitlangton is already working on this.

Since Sep 11, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

If the agent calls read on a .png file whose first bytes are not a PNG signature, the tool still reports Image read successfully and attaches the whole file as data:image/png;base64,.... The attachment is stored in the session and replayed on every following request, so the provider rejects every message from then on:

Error from provider (Console): Upstream request failed: [invalid_request_error] invalid image data at input[34].output[1]: the `image/png` payload could not be decoded (it may be corrupt or truncated).

There is no way to recover from inside OpenCode: new prompts, /compact attempts and plugin continuations all fail with the same error, because the tool result with the bad attachment is always included.

Root cause (unchanged on dev @ 193de13a88):

How it happened for real: adb exec-out screencap -p > shot.png on a multi-display Android phone writes a text warning ([Warning] Multiple displays were found, but no display id was specified! ..., 347 bytes) to stdout before the PNG bytes. file shot.png says data, but read happily attached it as image/png.

Expected: when the sniffed bytes don't match an image/PDF signature, don't attach the file as media (return an error like "file is not a valid PNG", or fall back to the text/binary path). Ideally also a recovery path: when a provider rejects a tool-result media part (400 invalid image), strip that attachment from history instead of failing forever. Related: #47487 (session bricked by image count, no recovery), #41163 (tool-result media 400s whole request).

Workaround that worked: clear state.attachments of that tool part in ~/.local/share/opencode/opencode.db (part table); the same session then works again.

Plugins

oh-my-opencode 4.19.4

OpenCode version

1.14.17 (code path verified identical on dev 193de13a88, 2026-09-10)

Steps to reproduce
  1. Make a "png" that is text followed by a real PNG:
    printf '[Warning] Multiple displays were found, but no display id was specified!\n' > bad.png
    cat some-valid.png >> bad.png
    file bad.png   # -> "data" (not a PNG)
    
  2. In OpenCode (any provider that accepts images; here provider opencode, model muse-spark-1.3-contributor-free), ask the agent to read bad.png. Tool output: Image read successfully, with an image/png attachment.
  3. Send any next message. Provider returns 400 invalid image data ... could not be decoded.
  4. Every further message in that session fails identically (the attachment is replayed from the session DB each time).
Screenshot and/or share link

No share link (session contains personal screenshots). The provider error text above is copied verbatim from the log (service=llm ... error=AI_APICallError ... statusCode 400).

Operating System

macOS 26.6.2 (Darwin 25.6.0, arm64)

Terminal

ghostty

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.