fix(call): send theme changes only once the call frame is ready (postMessage origin error) #478

Merged
jared merged 1 commits from fix/call-theme-before-ready into lotus 2026-10-28 20:52:06 -04:00
Owner

Reported by Jared (desktop app console, on joining a call):

Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://127.0.0.1:44548') does not match the recipient window's origin ('http://localhost:44548').

Cause: useCallThemeSync calls embed.setTheme() as soon as the call view mounts. The embed uses waitForIframeLoad: false, so that widget message goes out while the iframe is still on its initial about:blank.

  • about:blank has the app's origin (localhost), but the message is addressed to the call's origin (127.0.0.1), so the browser refuses it.
  • The request then hangs until the widget-API timeout.
  • The theme was correct anyway, since it's in the frame URL, so this was console noise plus a dangling request.
  • It shows up wherever the call page is on its own origin: the desktop app, and the web call. subdomain.

Fix (CallEmbed.ts): setTheme only records the theme until the widget API emits ready. On ready, it sends the latest theme if it differs from the one the frame loaded with, so a theme change made while the call is loading still applies. After that, theme changes are sent straight away as before.

Tested

  • Setup: the desktop situation reproduced locally (app on localhost:4173, call frame on 127.0.0.1:4173 via elementCallUrl), joining "Voice Lounge" against the local LiveKit stack.
    • Current lotus: the origin-mismatch error appears on join.
    • With this change: none.
  • 1,447 unit tests pass; lint is at 28 warnings; Prettier is clean.

🤖 Generated with Claude Code

https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5

**Reported by Jared** (desktop app console, on joining a call): ``` Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('http://127.0.0.1:44548') does not match the recipient window's origin ('http://localhost:44548'). ``` **Cause:** `useCallThemeSync` calls `embed.setTheme()` as soon as the call view mounts. The embed uses `waitForIframeLoad: false`, so that widget message goes out while the iframe is still on its initial `about:blank`. - `about:blank` has the **app's** origin (`localhost`), but the message is addressed to the call's origin (`127.0.0.1`), so the browser refuses it. - The request then hangs until the widget-API timeout. - The theme was correct anyway, since it's in the frame URL, so this was console noise plus a dangling request. - It shows up wherever the call page is on its own origin: the desktop app, and the web `call.` subdomain. **Fix (`CallEmbed.ts`):** `setTheme` only records the theme until the widget API emits `ready`. On `ready`, it sends the latest theme if it differs from the one the frame loaded with, so a theme change made while the call is loading still applies. After that, theme changes are sent straight away as before. **Tested** - **Setup:** the desktop situation reproduced locally (app on `localhost:4173`, call frame on `127.0.0.1:4173` via `elementCallUrl`), joining "Voice Lounge" against the local LiveKit stack. - **Current `lotus`:** the origin-mismatch error appears on join. - **With this change:** none. - 1,447 unit tests pass; lint is at 28 warnings; Prettier is clean. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared added 1 commit 2026-10-28 20:30:09 -04:00
fix(call): send theme changes only once the call frame is ready (postMessage origin error)
CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 3m24s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 11s
CI / Playwright smoke (e2e) (pull_request) Successful in 18m12s
2612f71c57
Reported from the desktop app console on joining a call: "Failed to execute
postMessage on DOMWindow: The target origin provided (http://127.0.0.1:44548)
does not match the recipient window origin (http://localhost:44548)".

useCallThemeSync calls embed.setTheme as soon as the call view mounts. With
waitForIframeLoad: false that send goes out while the iframe is still on its
initial about:blank, which has the app origin, so the browser refuses the
message addressed to the call origin and the request hangs to a timeout. The
theme was right anyway (it is in the frame URL), so this was noise plus a
pending request.

setTheme now only records the theme until the widget API is ready; on ready
it sends the latest theme if it differs from the one the frame loaded with.

Reproduced with the app on localhost and the call frame on 127.0.0.1 (as on
desktop) against the local LiveKit stack: joining logged the error before,
none after.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
jared scheduled this pull request to auto merge when all checks succeed 2026-10-28 20:30:17 -04:00
jared merged commit 3163829c57 into lotus 2026-10-28 20:52:06 -04:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#478