Skip to content

web: session delete silently no-ops on insecure origins (unguarded crypto.randomUUID) #48144

Closed as duplicate

Description

@moshangcheng

Report an opencode Issue

Summary

Deleting a session in the web app silently fails when the UI is opened over plain HTTP on a non-localhost origin. The session store's remove() calls crypto.randomUUID() unguarded; crypto.randomUUID is undefined in insecure contexts, so the click handler throws synchronously before any request is sent — no network call, no error toast. The same unguarded secure-context-only crypto API pattern also breaks image attachments and several copy actions on insecure origins.

Environment

  • opencode version: 0.0.0-beta-19271
  • OS: Linux 7.0.14-orbstack (x64) — server in an OrbStack-managed container; web UI accessed from Chrome on macOS
  • Terminal: n/a (web app)
  • Shell: /usr/bin/zsh
  • Install/channel: npm beta (@opencode-ai/cli@beta, global install)
  • Active plugins: none

Reproduction

  1. Start the server: opencode2 serve --hostname 0.0.0.0 --port 58640
  2. Open the web app in Chrome over plain HTTP using a non-localhost hostname (e.g. http://<container-hostname>:58640) — an insecure context where crypto.randomUUID is unavailable
  3. Open any session's menu and click Delete, then confirm
  4. Nothing happens

Expected Behavior

The session is deleted (DELETE /api/session/{id}), or at minimum the "Failed to delete session" toast appears.

Actual Behavior

No request is sent; no toast appears. The browser console shows:

Uncaught (in promise) TypeError: crypto.randomUUID is not a function
    at Object.remove (runtime-*.js)
    at x (index-*.js)          // click handler
    at HTMLButtonElement.r [as $$click]

Additional Context

  • Regression vs beta-19086: the 19086 web bundle only references crypto.randomUUID inside a guarded helper (existence check + Math.random-based UUID fallback). beta-19271's session store remove() uses it raw to build the optimistic-update op id ({ id: crypto.randomUUID(), type: 'remove', sessionID }) even though a guarded helper exists in the same file.
  • Because the throw is synchronous, the caller's .catch (delete-failure toast) never attaches — hence a fully silent failure.
  • Workaround: access via http://localhost:<port> (secure context) or HTTPS; deletion works normally there. The server-side DELETE endpoint is unaffected.
  • Consistently reproducible on any insecure origin.
  • Same pattern, same version — other insecure-origin breakages found in the beta-19271 bundle:
    • Image attachments fail: the shared attach handler (paste/drop/picker) calls crypto.subtle.digest unguarded (crypto.subtle is also undefined in insecure contexts) and then builds the attachment with a raw crypto.randomUUID() id.
    • Several copy actions fail: multiple unguarded navigator.clipboard.writeText calls (copy path, copy session ID, text-field copy buttons, error-card copy). Only one site uses an execCommand fallback.
    • Guarded helpers with proper fallbacks exist in the same bundles (wd() for UUIDs, an execCommand clipboard fallback), so the fix pattern is already established in the codebase.

Activity

  1. github-actions commented on Sep 9, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    These issues cover the same root cause (insecure-context Web Crypto API unavailability) and the same affected features (session delete, file attach, clipboard, image paste). Please review those threads and consider whether this report adds new information not already captured there.

  2. opencodejr commented on Oct 28, 2026

    @opencodejr

    Thanks for the detailed report! I think this is a duplicate of #46168, which reports the same silent session delete failure (crypto.randomUUID is not a function at Object.remove) on non-localhost HTTP origins, along with file attach failing.

    Possible duplicates and closely related issues, ordered by likelihood:

    Your list of other places that call crypto.randomUUID, crypto.subtle and navigator.clipboard without a fallback is useful. Please consider adding it to #46168 so it's all in one place. Until then, opening the UI via http://localhost:<port> or HTTPS works around it, as you found.

    The bot will close this issue as a duplicate in 1 day unless you reply explaining how your problem is different.

  3. opencodejr commented on Oct 29, 2026

    @opencodejr

    Closing this as a duplicate of #46168, which covers the same silent session delete failure (crypto.randomUUID is not a function in remove()) on non-localhost HTTP origins. We waited a day for a reply about how this might be different and didn't hear back. Please follow #46168 for updates; your list of other places that call crypto.subtle and navigator.clipboard without a fallback would be a useful comment there. The related issues are #46419 (image attachments) and #50988 (copy buttons). Until it's fixed, opening the UI via http://localhost:<port> or HTTPS works around it. If this turns out to be a different problem, reply here and we can reopen it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions