Skip to content

Troubleshooting

Before debugging specific issues, make sure you have an error listener attached so SDK errors surface in your console:

widget.on("error", (error) => {
console.error("Widget error:", error.message);
});

WidgetSDK can only be used in browser environment

Section titled “WidgetSDK can only be used in browser environment”

The SDK was instantiated outside a browser context, typically during server-side rendering. Move new WidgetClient(...) inside a useEffect call or any other code path that only runs in the browser. See the React integration guide for patterns.

The widgetKey option was not passed to the constructor. Check that your environment variable is set and that its value is being read before WidgetClient is created.

widget.init() was called twice on the same instance. Guard the call with a ref or flag, or create a new WidgetClient instance per session.

Widget not initialized. Call init() first.

Section titled “Widget not initialized. Call init() first.”

A method such as joinQueue() was called before widget.init() resolved. Wait for the ready event or for the init() promise to settle before calling other methods:

await widget.init(); // wait for this to resolve
await widget.joinQueue({ terms: true });

StatusMeaningFix
400Bad request — missing or malformed parametersCheck the widgetKey value and ensure page_url is a valid URL
403Forbidden — origin not allowlisted or domain not verifiedAdd and verify your domain in Settings → Widgets → Domains
404Widget not foundConfirm the widgetKey matches an existing, active widget
423Widget inactiveRe-activate the widget in the dashboard
429Rate limit exceededSee rate limiting below

Your widget key is missing or incorrect. Verify the value and ensure the domain you are calling from is allowlisted under Settings → Widgets → Domains.

The request origin does not match any allowlisted domain. Open Settings → Widgets, select your widget, and add your full origin including protocol (e.g. https://example.com). Domain verification is required before the origin will be accepted.


joinQueue() was called while the visitor is already queued. Check widget.getState() before calling joinQueue() and only call it from the ready state.

Cannot join queue while in call or assigned to agent

Section titled “Cannot join queue while in call or assigned to agent”

A session is already in progress. Listen to call:ended before allowing the visitor to re-enter a queue.

The realtime connection may have been interrupted. This is non-fatal — the SDK falls back to polling. If updates stop entirely, call widget.destroy() and reinitialise.


The public init endpoint is limited to 10 requests per minute per IP. This is almost always caused by calling widget.init() on every render.


Call UI does not appear after call:started

Section titled “Call UI does not appear after call:started”

The video conference script may have failed to load. Check your browser’s network tab for blocked requests. If you have a strict Content Security Policy (CSP), you may need to allowlist the conference provider’s domain.

A network error prevented the conference script from loading. Check your connection and any firewall or proxy rules that might block external scripts.

Parent node not found for video conference after timeout

Section titled “Parent node not found for video conference after timeout”

The DOM element the call UI should mount into was not found within 5 seconds. If you are using a custom container, make sure the element is present in the DOM before calling widget.init().


Agent requests cobrowsing but nothing happens

Section titled “Agent requests cobrowsing but nothing happens”

Make sure you are handling the cobrowse:consent:required event. Without a handler the consent prompt is never shown and cobrowsing cannot start:

widget.on("cobrowse:consent:required", ({ accept, decline }) => {
// You must call accept() or decline() — without this, cobrowsing will not start
});

Session tokens expire after 30 minutes and auth tokens after 15 minutes. If a visitor stays on the page for an extended period without completing a call, subsequent operations may fail with a token-expired error. Call widget.destroy() and create a new instance to reinitialise.