Skip to content

Fix loading images in opencode by handling data:png in URL construction#1845

Merged
NathanFlurry merged 2 commits into
rivet-dev:mainfrom
jlu-figma:jlu/new_fix
Jul 25, 2026
Merged

Fix loading images in opencode by handling data:png in URL construction#1845
NathanFlurry merged 2 commits into
rivet-dev:mainfrom
jlu-figma:jlu/new_fix

Conversation

@jlu-figma

@jlu-figma jlu-figma commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Summary

I was trying to use opencode with AgentOS as the filesystem backend, but found that my agent would crash whenever it tried to load images.

Turns out:

  • OpenCode's read tool returns images as a data URL (data:image/png...)
  • This triggers the NativeURL parsing through some path
  • The parsing in NativeURL tries to match either file: or full.match(/^([a-zA-Z][a-zA-Z\d+\-.]*:)(?!\/\/)/); (which is stuff like scheme://host/`, I believe)
  • However, this means urls like data: don't get processed and so nothing gets turned to the agent during image reading.

The change here is to add an opaque URL branch before the final backup regex above.

Testing

  • AGENTOS_BUILTIN_CONFORMANCE_CASE=url cargo test -p agentos-native-sidecar --test builtin_conformance __builtin_conformance_case_runner -- --exact — passes (guest fallback output matches host Node for the data:/mailto: cases and all pre-existing cases).

Alternative appraoches considerd

  • Thought about just addressing the data uri path, since that's the most important for me
  • Thought about adding a raise on the path where nothing matches.

@jlu-figma
jlu-figma marked this pull request as draft July 23, 2026 21:29
@jlu-figma jlu-figma changed the title fix(secure-exec): support opaque (data:/mailto:) URLs in fallback URL Fix loading images in opencode by handling data:png in URL constructoin Jul 23, 2026
@jlu-figma jlu-figma changed the title Fix loading images in opencode by handling data:png in URL constructoin Fix loading images in opencode by handling data:png in URL construction Jul 24, 2026
@jlu-figma
jlu-figma marked this pull request as ready for review July 24, 2026 00:08
@jlu-figma

Copy link
Copy Markdown
Contributor Author

@NathanFlurry can i get a look at this? Would love to use agent-os but this is a blocker

jlu-figma and others added 2 commits July 24, 2026 17:04
The fallback `NativeURL` implementation used when a native WHATWG `URL`
is unavailable (e.g. the secure-exec bootstrap replaces `globalThis.URL`
with a `__secureExecBootstrapStub`, so `canUseNativeUrlImplementation`
returns false) only parsed hierarchical `scheme://host` URLs and a
special case for `file:`. For any other scheme it fell through to:

    const match = full.match(/^(\w+:)\/\/([^/:?#]+)(:\d+)?(.*)$/);

An opaque URL such as `data:image/png;base64,...` or `mailto:a@b.com`
has no `//authority`, so `match` was null and every field defaulted to
empty, producing `href === "///"`, `protocol === ""` and `pathname
=== "/"`.

This breaks any guest code that round-trips a `data:` URL through
`new URL(...)`. Concretely, when OpenCode runs inside AgentOS and its
`read` tool returns an image as a `data:image/png;base64,...`
attachment, the AI SDK's `convertToLanguageModelPrompt` /
`validateDownloadUrl` call `new URL(dataUrl)` and check
`parsed.protocol === "data:"`. The corrupted URL fails that check and
raises `AI_DownloadError: Invalid URL: ///`, so no image ever reaches
the model turn.

Add a branch for opaque (non-hierarchical) URLs — any `scheme:` not
followed by `//` — before the hierarchical regex. It sets the protocol,
treats the remainder (minus query/hash) as an opaque pathname, reports
`origin === "null"`, and keeps `href`/`searchParams` in sync, matching
Node's WHATWG `URL` behavior. `file:` and `scheme://host` URLs are
unaffected (the negative lookahead `(?!\/\/)` lets them fall through).

Adds a `data:`/`mailto:` regression case to the `url` builtin
conformance test, which diffs guest V8 output against host Node.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The `searchParams`->`href` sync wiring was duplicated across the `file:`,
opaque, and hierarchical branches of the fallback `NativeURL` constructor,
each with its own inline `["append","delete","set","sort"]` list. Factor it
into a single `bindSearchParams(buildHref)` helper driven by a shared
`SEARCH_PARAM_SYNC_METHOD_NAMES` constant, so each branch only supplies its
own `href` builder. No behavior change; the `url` builtin conformance test
(guest V8 vs host Node) still passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants