Troubleshooting
Listen for errors first
Section titled “Listen for errors first”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);});Initialisation errors
Section titled “Initialisation errors”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.
widgetKey is required
Section titled “widgetKey is required”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 already initialized
Section titled “Widget already initialized”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 resolveawait widget.joinQueue({ terms: true });HTTP errors
Section titled “HTTP errors”| Status | Meaning | Fix |
|---|---|---|
400 | Bad request — missing or malformed parameters | Check the widgetKey value and ensure page_url is a valid URL |
403 | Forbidden — origin not allowlisted or domain not verified | Add and verify your domain in Settings → Widgets → Domains |
404 | Widget not found | Confirm the widgetKey matches an existing, active widget |
423 | Widget inactive | Re-activate the widget in the dashboard |
429 | Rate limit exceeded | See rate limiting below |
401 Unauthorized on init
Section titled “401 Unauthorized on init”Your widget key is missing or incorrect. Verify the value and ensure the domain you are calling from is allowlisted under Settings → Widgets → Domains.
403 Forbidden — origin mismatch
Section titled “403 Forbidden — origin mismatch”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.
Queue errors
Section titled “Queue errors”Already in queue
Section titled “Already in queue”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.
Queue position stops updating
Section titled “Queue position stops updating”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.
Rate-limit errors (429)
Section titled “Rate-limit errors (429)”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.
Video call errors
Section titled “Video call errors”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.
Failed to load video call API
Section titled “Failed to load video call API”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().
Cobrowsing errors
Section titled “Cobrowsing errors”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});Token expiry
Section titled “Token expiry”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.