Repository navigation
Description
Description
On the Web UI served over plain HTTP from a non-localhost origin (LAN IP / hostname / Tailscale), clicking Open file in the side panel's new-tab view does nothing: no tab opens, no toast, no request. The console shows:
Uncaught TypeError: crypto.randomUUID is not a function
Review and Terminal launchers in the same panel work. The same server and session work over http://127.0.0.1:<port>.
Root cause: packages/gui-plugins/src/file/renderer.tsx opens a new launcher tab with an unguarded crypto.randomUUID():
https://github.com/anomalyco/opencode/blob/v2.2.0/packages/gui-plugins/src/file/renderer.tsx#L170
if (selected || layout.narrow())
layout.open(`file:${selected ?? OPEN}`, session, { tab: "preview", background: options?.background })
else layout.open(`file:${OPEN}:${crypto.randomUUID()}`, session, { tab: "select" })crypto.randomUUID exists only in secure contexts, so on an insecure origin the call throws inside the click handler before layout.open, and the click is silently lost. Both the + → “Open file” launcher and Ctrl+Alt+P reach this branch; narrow layouts (<768px) take the other branch and are unaffected.
Steps to reproduce
- Start the Web UI (
opencode serve, or the background service) and open it from a non-localhost HTTP origin, e.g.http://<LAN-IP>:<port>/(Chrome shows “Not secure”). - Open any session and open the side panel (Toggle review).
- Click
+(Add tab), then Open file. - Nothing happens; devtools shows
TypeError: crypto.randomUUID is not a function.
Expected: the file browser tab opens on any origin (id generation should not require a secure context).
Regression / history
v2.1.4used a fixed key (file:open) inopenPickerand worked on insecure origins.#57182(879479b467, “allow multiple open file tabs”) introducedfile:${OPEN}:${crypto.randomUUID()};#55246moved it topackages/gui-plugins/src/file/renderer.tsx. First release containing it: v2.2.0.- The app already has a guarded helper for exactly this:
uuid()inpackages/app/src/runtime/persistence/uuid.ts(falls back whencrypto.randomUUIDis unavailable, whenisSecureContextis false, or when it throws), with unit tests. Earlier fixes#51783and#53501were the same class of bug. - Related open issues:
#46168,#48144,#55777(other unguardedcrypto.randomUUIDcalls that silently fail on insecure origins).
Suggested fix
Use the guarded helper here — e.g. promote uuid() to @opencode/util and import it from both the app and packages/gui-plugins, or add a local fallback before layout.open:
const uuid = () =>
typeof globalThis.crypto?.randomUUID === "function" && globalThis.isSecureContext !== false
? globalThis.crypto.randomUUID()
: Math.random().toString(16).slice(2)Worth auditing the other direct calls reachable from the web UI: packages/gui-plugins/src/btw/model.ts:107 and packages/app/src/runtime/plugin/host-apis.tsx:1026.
Verification
Control experiment on the same server/session in Chromium:
http://127.0.0.1:<port>: clicking Open file opens the “Open file” tab and shows “Select a file to open”.- Same page with
Crypto.prototype.randomUUIDremoved (equivalent to an insecure context): the click logsTypeError: crypto.randomUUID is not a function, the tab strip still shows only “New tab”; clicking Terminal right after opens “Terminal 1” normally. - On the insecure origin,
typeof crypto.randomUUIDevaluates to"undefined"andisSecureContextisfalse.
Environment
- OpenCode: v2.2.0
- OS: Ubuntu 24.04 (Linux 7.0.0-34-generic)
- Browser: Chrome 155.0.8059.39
- Web UI: served by the local service, accessed via
http://<LAN-IP>:<port> - Plugins: none relevant (built-in
file,terminalGUI plugins only)
Activity
opencodejr commentedon Oct 28, 2026
Thanks for the detailed report. I reproduced this on v2.2.0, and it still happens on the latest
dev(86ce19d).opencode serve --hostname 0.0.0.0and opened the web UI in Chromium at the machine's LAN IP over plain HTTP (isSecureContextisfalse,crypto.randomUUIDis undefined).TypeError: crypto.randomUUID is not a function, and the tab strip still showed only "New tab".The same steps on
http://127.0.0.1open the "Open file" tab with "Select a file to open". The screenshots below show both cases, and the script below reproduces it. The unguarded call inpackages/gui-plugins/src/file/renderer.tsxis still there ondev.Related issues:
btwcommandReproduction script (repro.mjs)
Run it:
bun repro.mjsAeromtrich commentedon Oct 28, 2026
I'd like to work on this issue. Is anyone already working on a fix? If not, I'd be happy to take it. 🧐