Repository navigation
Description
Summary
packages/opencode/src/acp/agent.ts:1394 reads:
} else if (part.uri && part.uri.startsWith("http:")) {This prefix only matches http:// URLs. https:// URLs do not start with "http:" (the 5th char is s, not :), so they fall through the case "image": branch with no parts.push — the image is silently dropped from the prompt with no error or warning.
Reproducer
Send an ACP session/prompt request with an image content block whose uri is https://:
{
"type": "image",
"uri": "https://storage.googleapis.com/bucket/img.png",
"mimeType": "image/png"
}Expected: image part is forwarded to the LLM provider as a file part.
Actual: case falls through, no parts.push runs, image disappears from the prompt.
This breaks every ACP client that does two-stage uploads (sign a GCS / S3 URL, send the URL via ACP rather than inlining base64) — those URLs are always https://.
Why it's almost certainly a typo
Every other URL check in this codebase uses both prefixes:
| File | Pattern |
|---|---|
packages/opencode/src/session/instruction.ts:146,168 |
startsWith("https://") || startsWith("http://") |
packages/opencode/src/cli/cmd/import.ts:98 |
startsWith("http://") || startsWith("https://") |
packages/opencode/src/tool/webfetch.ts:23 |
!startsWith("http://") && !startsWith("https://") |
packages/opencode/src/config/config.ts:1270 |
startsWith("http://") || startsWith("https://") |
Only acp/agent.ts:1394 is missing the https:// half. Probably a mid-edit drop of / while typing "http://".
Proposed fix
One-line:
- } else if (part.uri && part.uri.startsWith("http:")) {
+ } else if (part.uri && (part.uri.startsWith("http://") || part.uri.startsWith("https://"))) {Happy to send the PR. Will include a unit test asserting that https://example.com/x.png produces a forwarded file part. Opening this issue first per CONTRIBUTING.md issue-first policy.
Environment
- Repo: anomalyco/opencode
- Branch: dev
- File: packages/opencode/src/acp/agent.ts (line 1394 at HEAD)
Note
I previously opened PR #24772 with this fix without a linked issue — auto-closed by the bot. Re-doing it properly: issue first, then PR with Fixes #<this>.
Activity
fix(acp): match https:// URIs in ACP image content blocks