Skip to content

fix(remote): queue messages without Web Crypto randomUUID - #3232

Open
bobleer wants to merge 1 commit into
GCWing:mainfrom
bobleer:bob/fix-queue-id-fallback
Open

bobleer wants to merge 1 commit into
GCWing:mainfrom
bobleer:bob/fix-queue-id-fallback

Conversation

@bobleer

@bobleer bobleer commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Fixes a regression from #3180 (host-owned mobile message queues): the queue identified turns and operations with crypto.randomUUID(), which browsers expose only in secure contexts.

  • Symptom: sending a message from the remote control page (or the desktop composer) fails with the raw crypto.randomUUID is not a function banner, and nothing is queued.
  • Root cause: src/shared/dialog-queue/HostDialogQueue.ts (newId) was the only unguarded crypto.randomUUID call on these paths. Every other call site in the repo already guards it (CloudAccountClient.generateRequestId, copyToClipboard's explicit "insecure contexts (HTTP)" fallback, and the many typeof checks in web-ui).
  • Why it reaches users: LAN remote control serves the remote page over plain HTTP (http://<lan-ip>:9700, RemoteConnectDialog / build_lan_relay_url), so randomUUID is missing in every browser there. Old in-app browsers / WebViews over the official HTTPS relay hit the same gap.
  • Fix: derive a v4 UUID from crypto.getRandomValues, which insecure contexts still expose, and leave the secure-context call unchanged.

Fixes #3180 (regression introduced there).

Type and Areas

Type: regression fix

Areas: web UI, mobile web (shared module src/shared/dialog-queue, used by the remote page and the desktop composer)

Motivation / Impact

A user controlling a machine over LAN could reach the session and receive assistant output, but nothing they typed could be queued — every send died locally in JS. The same shared module now also backs desktop composer sends, so an old Linux WebKit build fails identically. No host, relay, protocol, or wording change; only the id source when randomUUID is absent.

Verification

  • cd src/mobile-web && node --test tests/host-dialog-queue.test.mjs — 14/14 pass, including the new case that stubs a crypto without randomUUID and asserts both the queued turnId and the promote operationId are v4 UUIDs.
  • Before/after check on the module itself (pre-fix source from HEAD vs this commit, same crypto stub): pre-fix rejects with crypto.randomUUID is not a function; fixed accepts and returns c1ab8814-ec71-4ace-bed8-9d2284309a7e.
  • pnpm --dir src/mobile-web run type-check — pass.
  • pnpm --dir src/web-ui run type-check — pass (after pnpm --dir src/web-ui run gen:types).
  • pnpm --dir src/web-ui exec vitest run src/flow_chat/components/HostPendingQueuePanel.test.tsx — 4/4 pass.
  • Not run locally: the puppeteer half of test:host-queue (no Chromium on this host), and the whole test:host-queue suite is not part of the Frontend Build job. CI covers type-check/build for this change.

Reviewer Notes

  • Secure-context behaviour is byte-for-byte unchanged: the randomUUID branch is what already ran there.
  • The fallback is a local helper in the same file (mirrors CloudAccountClient.generateRequestId) rather than a new shared util, to keep the diff reviewable; happy to extract it if you prefer one owner for id generation.
  • Delivery: the remote page bundle must be republished with the next relay page deploy, and LAN-mode pages ship inside the desktop build, so affected users need that release to get the fix.
  • AI-assisted: yes — co-authored by the bitfun-ai account. Testing level: fully tested for the changed module (unit + focused suites + type-checks above); no end-to-end LAN run.

Checklist

  • This PR is focused and does not include secrets, temporary prompts, generated scratch files, or unrelated artifacts.
  • Relevant verification is recorded above, or skipped checks are explained.
  • User-facing strings, docs, and locales are updated where applicable. (No user-facing copy added; the fix removes an untranslated raw error.)

Host queue turns and operations were identified with `crypto.randomUUID()`,
which browsers expose only in secure contexts. The remote page that LAN mode
serves over plain HTTP, and older WebViews, therefore failed every send with
"crypto.randomUUID is not a function" (regression from GCWing#3180).

Derive a v4 UUID from `crypto.getRandomValues`, which those environments still
provide, and keep the secure-context call unchanged.

Co-authored-by: OpenBitFun <318544290+bitfun-ai@users.noreply.github.com>
@bobleer

bobleer commented Sep 26, 2026

Copy link
Copy Markdown
Collaborator Author

@GCWing CI is green — Frontend Build, Rust Build Check (macOS/Ubuntu/Windows), CLI Tests (macOS/Ubuntu/Windows), Build Impact, Repository Object Sizes and Shell Deploy Scripts all pass (the two skipped jobs are impact-selected off for a frontend-only change). This is ready for your review and merge.

Context for review: a regression from #3180. HostDialogQueue identified turns and operations with an unguarded crypto.randomUUID(), which browsers expose only in secure contexts. LAN remote control serves its page over plain HTTP (http://<lan-ip>:9700), so every send there died locally with the raw crypto.randomUUID is not a function banner; old in-app browsers on the official relay hit the same gap. The fix derives the id from crypto.getRandomValues when randomUUID is missing; the secure-context path is untouched. Verified with the mobile-web host-queue suite (14/14, one new case stubbing a crypto without randomUUID), a before/after check on the module, both type-checks, and the focused web-ui queue panel tests.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant