Skip to content

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) #48476

Description

@ez2sarang

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 @ 193de13):

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 193de13, 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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions