Skip to content

--file flag hardcodes text/plain for all attachments breaking image uploads #34318

Closed

Description

@MADEVAL

Description

When using the --file flag in local mode, all files are hardcoded as text/plain regardless of their actual type. Image files (PNG, JPEG, etc.) are passed to the LLM as garbled UTF-8 text instead of base64-encoded images.

Root cause: run.ts line 385 hardcodes mime to "text/plain" for all non-directory files when not in --attach mode. FSUtil.mimeType is already called on line 380 but the result is discarded. Downstream in session/prompt.ts, part.mime is trusted as-is with no re-detection, so text/plain routes images through the Read-tool text path instead of the base64 data: URL path.

Plugins

None

OpenCode version

dev branch

Steps to reproduce

  1. Run: opencode -f image.png "describe this image"
  2. The LLM receives garbled binary text instead of a base64-encoded image

Operating System

All

Terminal

All

Activity

  1. github-actions commented on Jun 28, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is different, please add more context explaining how it differs from the above.

  2. akaguny commented on Aug 11, 2026

    @akaguny

    Still reproducible in v1.18.16 (latest release, 2026-08-10).

    Reproduction on Linux, opencode v1.18.16, custom OpenAI-compatible provider (RouterAI) with a vision model declared as attachment: true + modalities: {input: ["text", "image"]}:

    opencode run "What is written in the attached image?" \
      --model routerai/qwen/qwen3-vl-30b-a3b-instruct \
      -f /tmp/vision_test.png
    

    Result: the model responds "The model does not support image input." and the server log shows:

    message=file mime=text/plain
    

    The root cause is still exactly as described here: in packages/opencode/src/cli/cmd/run.ts, local (non---attach) mode hardcodes the MIME type:

    const mime = !args.attach
      ? isDirectory
        ? "application/x-directory"
        : "text/plain"          // <- FSUtil.mimeType(path) result on the line above is discarded
      : content && text !== undefined && Buffer.from(text, "utf8").equals(content)
        ? "text/plain"
        : detected

    FSUtil.mimeType() (mime-types lookup()) already returns image/png correctly for the same path — the value just never gets used in local mode.

    Two fix PRs (#34319, #34369) were closed unmerged; the bug has been open since 2025 (#16723, #24698, #25353, #38952). Suggested one-line fix:

    const mime = isDirectory ? "application/x-directory" : detected

    Worth noting: with attachment + modalities declared in the provider config, the TUI attachment path and the server API (POST /session/{id}/message with a data:image/png;base64,... file part) both deliver images correctly — only the run --file CLI path is affected.

  3. neriousy commented on Oct 1, 2026

    @neriousy
    Member

    In OpenCode v2, opencode run --file keeps the detected type for images and PDFs, so they reach the model as real image/PDF attachments. Only other UTF-8 text files are sent as text/plain.

    Fixed in #35526.

    Closing as completed. If something doesn't work on v2, please open a new issue.

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