Description
When accessing the OpenCode web UI served by opencode serve via plain HTTP on a non-localhost origin (e.g. http://<server-ip>:4096), pasting an image into the chat composer throws and the image is not displayed:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'digest')
at fX (index-DgVTS9m-.js:1484:2435)
at Object.putBlob (index-DgVTS9m-.js:1484:5308)
at Object.n [as store] (index-DgVTS9m-.js:1484:2652)
at n (index-DgVTS9m-.js:1497:7804)
at async index-DgVTS9m-.js:1497:8293
at async r (index-DgVTS9m-.js:1497:8242)
at async Object.i [as handlePaste] (index-DgVTS9m-.js:1497:8607)
Root cause analysis
blobID() in packages/app/src/utils/draft-store.ts (introduced in PR #40207, v1.18.13)
calls crypto.subtle.digest("SHA-256", ...). In a non-secure context (plain HTTP
on anything other than localhost / 127.0.0.1 / *.localhost), the Web Crypto
API spec causes window.crypto.subtle to be undefined (see MDN: Secure Contexts).
Accessing .digest on undefined throws the TypeError above.
Related: PR #40207 introduced the IndexedDB-backed blob storage; PR #40692 / v1.18.15
only fixed CSP for blob: URLs, not this crypto.subtle code path.
Suggested fix
Add a graceful fallback in blobID() when crypto?.subtle is undefined — e.g. a
pure-JS SHA-256 implementation (spark-md5 / js-sha256), a non-cryptographic id, or
at minimum a clear error message like "Image attachments require HTTPS (secure
context)."
Workaround for users
- Access via
http://localhost:4096 or 127.0.0.1
- Set up an HTTPS reverse proxy (e.g. Caddy auto-TLS, nginx + cert)
Plugins
No response
OpenCode version
1.18.14
Steps to reproduce
- Install OpenCode v1.18.13+ on a remote server (Linux, openEuler 22.03)
- Run
opencode serve — it listens on 0.0.0.0:4096
- From any client machine, open the web UI at
http://<server-ip>:4096
(must NOT be localhost — HTTP on remote IP is the trigger)
- Paste an image (Ctrl+V / Cmd+V) into the chat composer
- Image does not appear; browser devtools console shows the
digest TypeError above
Screenshot and/or share link
Operating System
openEuler 22.03 LTS-SP2 (Linux 5.10, x86_64); client tested on Chrome / Edge
Terminal
N/A (Web UI in Chrome browser)
Description
When accessing the OpenCode web UI served by
opencode servevia plain HTTP on a non-localhost origin (e.g.http://<server-ip>:4096), pasting an image into the chat composer throws and the image is not displayed:Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'digest')
at fX (index-DgVTS9m-.js:1484:2435)
at Object.putBlob (index-DgVTS9m-.js:1484:5308)
at Object.n [as store] (index-DgVTS9m-.js:1484:2652)
at n (index-DgVTS9m-.js:1497:7804)
at async index-DgVTS9m-.js:1497:8293
at async r (index-DgVTS9m-.js:1497:8242)
at async Object.i [as handlePaste] (index-DgVTS9m-.js:1497:8607)
Root cause analysis
blobID()inpackages/app/src/utils/draft-store.ts(introduced in PR #40207, v1.18.13)calls
crypto.subtle.digest("SHA-256", ...). In a non-secure context (plain HTTPon anything other than
localhost/127.0.0.1/*.localhost), the Web CryptoAPI spec causes
window.crypto.subtleto beundefined(see MDN: Secure Contexts).Accessing
.digestonundefinedthrows the TypeError above.Related: PR #40207 introduced the IndexedDB-backed blob storage; PR #40692 / v1.18.15
only fixed CSP for
blob:URLs, not thiscrypto.subtlecode path.Suggested fix
Add a graceful fallback in
blobID()whencrypto?.subtleis undefined — e.g. apure-JS SHA-256 implementation (spark-md5 / js-sha256), a non-cryptographic id, or
at minimum a clear error message like "Image attachments require HTTPS (secure
context)."
Workaround for users
http://localhost:4096or127.0.0.1Plugins
No response
OpenCode version
1.18.14
Steps to reproduce
opencode serve— it listens on 0.0.0.0:4096http://<server-ip>:4096(must NOT be localhost — HTTP on remote IP is the trigger)
digestTypeError aboveScreenshot and/or share link
Operating System
openEuler 22.03 LTS-SP2 (Linux 5.10, x86_64); client tested on Chrome / Edge
Terminal
N/A (Web UI in Chrome browser)