anomalyco / anomalyco/opencode

read tool returns 2-year-expired DashScope OSS signed URL to vision model → model hallucinates image content

Open
#41,670 2 comments 0 reactions 1 assignee View on GitHub

@kitlangton is already working on this.

Since Aug 11, 2026.

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

Description

Description

When a vision-capable custom provider model (DashScope / Alibaba qwen-vl-max via openai-compatible) reads a local image through the read tool (in a subagent), the tool result contains a pre-signed DashScope OSS URL that expired ~2 years ago instead of base64 image data. The model cannot fetch the dead URL, and instead of erroring it hallucinates a plausible but completely fabricated description of the image.

Evidence

read tool result for D:\730_864.jpg (a real local file, 2560x1440, verified with Get-FileHash):

{
  "type": "image",
  "content": "https://qwen-vl-max-imgs.s3-accelerate.amazonaws.com/730_864.jpg?Expires=1723425439&OSSAccessKeyId=LTAI5tGhLdJbYkxTfHrUyvXK&Signature=PZ%2FmN0uWpBQvRnC8MfVq3ZoKg4c%3D"
}
  • Expires=1723425439 = 2024-08-12 (today is 2026-08-11) — the signature is stale by ~2 years.
  • Fetching that URL returns 403 Forbidden.
  • The vision model then "describes" the image with fabricated content (twice, two different hallucinations: once a webpage UI, once an indoor room — neither matches the actual image).
Diagnosis performed
  1. Confirmed the image file itself is fine: System.Drawing loads it (2560x1440 JPEG), Get-FileHash works.
  2. Sent the exact same image directly to DashScope's OpenAI-compatible endpoint (https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions, model qwen-vl-max) as a base64 image_url data URI via Invoke-RestMethodworks perfectly, returns an accurate description (a CS2 IEM Cologne 2026 Major collectible coin UI popup).
  3. So the API/model are fine; the bug is opencode's image pipeline: it hands the model an expired signed URL instead of base64 bytes.
Steps to reproduce
  1. Configure DashScope as a custom openai-compatible provider with a vision model (e.g. qwen-vl-max, attachment: true, modalities.input: ["text","image"]).
  2. Create a subagent with that model (or read an image in the main session on that model).
  3. read a local image file (ideally one whose filename matches a previously-uploaded DashScope object, e.g. 730_864.jpg — see note below).
  4. Observe the tool result URL is expired; the model either errors or hallucinates.
Note on suspected root cause

The returned URL object name equals the local filename (730_864.jpg), and the expiry is from 2024 — strongly suggesting opencode (or its DashScope upload path) caches the signed OSS URL keyed by filename (or served a stale cached URL) rather than uploading fresh bytes per read. Renaming the file to a new unique name may reproduce differently — worth checking whether the URL is regenerated per request.

Expected behavior

Reading a local image via read should deliver the actual image bytes (base64 data URI) to the vision model — same as sending base64 directly to the same provider, which works.

Environment
  • OS: Windows 11 (native, no WSL)
  • opencode: latest as of 2026-08-11
  • Provider: custom openai-compatible → DashScope qwen-vl-max

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.