anomalyco / anomalyco/opencode
[Bug] Web UI CSP blocks `blob:` URLs — dragging an image into chat fails with "NetworkError when attempting to fetch resource"
@Brendonovich is already working on this.
Since Aug 6, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
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 athttp://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 byconnect-src→ throwsNetworkError<img src="blob:...">previews → blocked byimg-src
Steps to reproduce
- Run
opencode weband openhttp://localhost:4096in Firefox. - Drag an image file into the chat input.
- Send the message.
- 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.pngin the input (server reads the file directly; avoidsblob: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
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.