Skip to content

[Bug] Web UI CSP blocks blob: URLs — dragging an image into chat fails with "NetworkError when attempting to fetch resource" #40814

Closed as not planned

Description

@ppyuehui

Description

Environment

  • opencode version: 1.18.12 (npm install -g opencode-ai, opencode-windows-x64)
  • OS: Windows 10/11
  • Browser: Firefox (error message "NetworkError when attempting to fetch resource" is Firefox-specific; Chrome shows "Failed to fetch")
  • Setup: opencode web, accessed at http://localhost:4096

Description

Dragging an image into the web chat input and sending it always fails. The message never reaches the server (no message=process entry appears in the server log for the failed attempt), so the failure is entirely client-side.

Browser console shows the real cause — the server's own Content-Security-Policy blocks the blob: URLs the web client uses to read back the dropped image:

Content-Security-Policy: ... blocked loading ... blob:http://localhost:4096/<uuid> (connect-src)
Content-Security-Policy: ... blocked loading ... blob:http://localhost:4096/<uuid> (img-src)

The CSP header is served by the opencode server itself for the web UI (HEAD / response):

Content-Security-Policy: default-src 'self'; script-src 'self' 'wasm-unsafe-eval' 'sha256-...';
  style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; font-src 'self' data:;
  media-src 'self' data:; connect-src * data:

Neither img-src nor connect-src includes blob:. Per the CSP spec, the * wildcard does not match the blob: scheme, so:

  • fetch(blob.url) → blocked by connect-src → throws NetworkError
  • <img src="blob:..."> previews → blocked by img-src

Steps to reproduce

  1. Run opencode web and open http://localhost:4096 in Firefox.
  2. Drag an image file into the chat input.
  3. Send the message.
  4. Toast shows "Failed to send prompt"; console shows the CSP violations above.

Expected behavior

Images dropped into the web chat are base64-encoded and sent to the server (or otherwise processed), as designed.

Root cause analysis

The web client (packages/app) stores dropped images in IndexedDB and references them via URL.createObjectURL(blob) (packages/app/src/utils/draft-store.ts). On send, blobDataUrl() first does fetch(blob.url) to read the blob back into a base64 data URL (draft-store.ts), then posts it inline in the JSON body of POST /session/{id}/prompt_async (packages/app/src/components/prompt-input/submit.ts).

That fetch(blob.url) on a blob: URL is blocked by the server's CSP connect-src * data: directive, producing the NetworkError. The failing request therefore never reaches the server. The same CSP also blocks inline <img> previews of blob: URLs via img-src.

There is no separate image-upload endpoint; images are embedded inline as base64, so the blob: fetch step is on the critical path for every image attachment in the web UI.

Suggested fix

Include blob: in the CSP directives, e.g.:

img-src 'self' data: blob: https:;
connect-src * data: blob:

(or the minimum required: img-src and connect-src must allow blob:).

Longer term, moving attachments to a dedicated upload endpoint (write blob server-side, reference by ID) would also avoid inlining multi-MB base64 into a single JSON POST, but the CSP fix alone resolves this specific failure.

Workarounds (current)

  • Attach the image by its file path via @C:\path\image.png in the input (server reads the file directly; avoids blob: fetch).
  • Use the TUI (opencode) which is not affected by the browser CSP.

Logs

  • Server log (~/.local/share/opencode/log/opencode.log): no entries for the failed send — confirms the request never reached the server.

Plugins

No response

OpenCode version

No response

Steps to reproduce

No response

Screenshot and/or share link

No response

Operating System

No response

Terminal

No response

Activity

  1. rayansostenes commented on Aug 6, 2026

    @rayansostenes

    Having the same problem here

  2. GuoChen-thlg commented on Aug 7, 2026

    @GuoChen-thlg

    This has already been fixed in version 1.18.15.

  3. github-actions commented on Oct 8, 2026

    @github-actions
    Contributor

    To stay organized issues are automatically closed after 60 days of no activity. If the issue is still relevant please open a new one.

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