openclaw - 💡(How to fix) Fix [Bug]: Canvas WebSocket creation in browser context silently swallows initialization errors [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

In extensions/canvas/src/host/a2ui-shared.ts (injected into HTML via injectCanvasLiveReload()), the WebSocket connection to the canvas host is created inside a try {} catch {} block (lines 54-62). If the WebSocket construction throws due to an invalid URL, network unavailability, or browser security policy, the error is silently swallowed with an empty catch block. The canvas host feature fails silently and the operator has no indication that canvas connectivity is broken. The empty catch {} at line 62 discards any error from WebSocket construction. There is no finally block, no error logging, and no user-visible error state. The connection attempt simply fails silently. 4. Observe that the page loads without any error indication 5. The canvas functionality is unavailable but no error is shown to the operator Root Cause: The try {} catch {} block wraps only the WebSocket construction and onmessage handler registration. If new WebSocket(...) throws (invalid URL, network unavailable, browser restrictions), the error is caught and discarded. The code continues executing as if the canvas were connected, but no actual connection exists. Concurrency Scenario: If the WebSocket connection drops after initialization and the browser does not fire onclose reliably (e.g., due to aggressive browser optimizations for background tabs), the onmessage handler never fires and any canvas-driven reload commands are lost without error indication. Add error handling in the catch block to display a visible error state or log the error to the console. Consider using a fallback approach (e.g., polling the canvas status endpoint) when WebSocket initialization fails, or at minimum surface an error badge in the UI so operators know canvas connectivity is unavailable.

Root Cause

The issue crosses a documented trust boundary because attacker-controlled input can trigger behavior that the protected component should reserve for authorized callers. This is exploitable vulnerability behavior rather than advisory hardening because the current implementation permits a concrete security property violation.

Fix Action

Fixed

Code Example

try {
  const cap = new URLSearchParams(location.search).get("oc_cap");
  const proto = location.protocol === "https:" ? "wss" : "ws";
  const capQuery = cap ? "?oc_cap=" + encodeURIComponent(cap) : "";
  const ws = new WebSocket(proto + "://" + location.host + ${JSON.stringify(CANVAS_WS_PATH)} + capQuery);
  ws.onmessage = (ev) => {
    if (String(ev.data || "") === "reload") location.reload();
  };
} catch {}
RAW_BUFFERClick to expand / collapse

Severity Assessment

CVSS Assessment

Metricv3.1v4.0
Score7.5 / 10.08.7 / 10.0
SeverityHighHigh
VectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:HCVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N
CalculatorCVSS v3.1 CalculatorCVSS v4.0 Calculator

Threat Model Alignment

Classification: security-specific

The issue crosses a documented trust boundary because attacker-controlled input can trigger behavior that the protected component should reserve for authorized callers. This is exploitable vulnerability behavior rather than advisory hardening because the current implementation permits a concrete security property violation.

Impact

In extensions/canvas/src/host/a2ui-shared.ts (injected into HTML via injectCanvasLiveReload()), the WebSocket connection to the canvas host is created inside a try {} catch {} block (lines 54-62). If the WebSocket construction throws due to an invalid URL, network unavailability, or browser security policy, the error is silently swallowed with an empty catch block. The canvas host feature fails silently and the operator has no indication that canvas connectivity is broken.

Affected Component

File: extensions/canvas/src/host/a2ui-shared.ts:54-62

try {
  const cap = new URLSearchParams(location.search).get("oc_cap");
  const proto = location.protocol === "https:" ? "wss" : "ws";
  const capQuery = cap ? "?oc_cap=" + encodeURIComponent(cap) : "";
  const ws = new WebSocket(proto + "://" + location.host + ${JSON.stringify(CANVAS_WS_PATH)} + capQuery);
  ws.onmessage = (ev) => {
    if (String(ev.data || "") === "reload") location.reload();
  };
} catch {}

The empty catch {} at line 62 discards any error from WebSocket construction. There is no finally block, no error logging, and no user-visible error state. The connection attempt simply fails silently.

Technical Reproduction

  1. Open the OpenClaw Control UI in a browser
  2. Navigate to a page that initializes the canvas host (/?oc_cap=...)
  3. Block the WebSocket connection (browser DevTools → Network → offline mode, or firewall)
  4. Observe that the page loads without any error indication
  5. The canvas functionality is unavailable but no error is shown to the operator

Demonstrated Impact

Root Cause: The try {} catch {} block wraps only the WebSocket construction and onmessage handler registration. If new WebSocket(...) throws (invalid URL, network unavailable, browser restrictions), the error is caught and discarded. The code continues executing as if the canvas were connected, but no actual connection exists.

What Breaks:

  • Canvas host connectivity failures are invisible to the operator
  • location.reload() triggers from the canvas host are never received
  • The operator cannot distinguish between "canvas not available" and "canvas working but no reload received yet"
  • Debugging canvas connectivity issues requires browser DevTools Network tab inspection

Concurrency Scenario: If the WebSocket connection drops after initialization and the browser does not fire onclose reliably (e.g., due to aggressive browser optimizations for background tabs), the onmessage handler never fires and any canvas-driven reload commands are lost without error indication.

Environment

Verified against openclaw/openclaw tag v2026.5.12 at commit main (published 2026-05-14T18:28:04Z). Canvas host browser script in Control UI on Chrome/Safari.

Remediation Advice

Add error handling in the catch block to display a visible error state or log the error to the console. Consider using a fallback approach (e.g., polling the canvas status endpoint) when WebSocket initialization fails, or at minimum surface an error badge in the UI so operators know canvas connectivity is unavailable.

<!-- submission-marker:CA-bpp-canvas-ws-silent-failure -->

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix [Bug]: Canvas WebSocket creation in browser context silently swallows initialization errors [1 pull requests]