> ## Documentation Index
> Fetch the complete documentation index at: https://docs.orbit.devotel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting: co-browse session stuck

> Diagnose a co-browse session that never starts, a frame blocked by CSP or X-Frame-Options, a dropped data-channel socket, and a guided-control or custom-tool packet that returned a 502 — plus how to read session errors from the activity feed.

# Troubleshooting: co-browse session stuck

A co-browse session moves through a short lifecycle: the visitor starts it
from the chat widget, an agent joins the data-channel room, and guided
control packets flow once the visitor granted control. A session that is
"stuck" broke at one of those steps, and the error your integration saw —
`COBROWSE_NOT_ACTIVE`, a browser frame-policy block, a dropped socket, or a
`CUSTOM_TOOL_RESPONSE_TOO_LARGE` (502) — names the step.

This page works one stuck co-browse down to a cause. The full join, end,
privacy, and control workflow is on the [Co-browse API](/api-reference/cobrowse)
reference; this page is the remedy ladder for each failure class.

## Symptom map

### `COBROWSE_NOT_ACTIVE` on join — the session never started

`POST /api/v1/cobrowse/{conversationId}/join` returns
`404 COBROWSE_NOT_ACTIVE` when the conversation has no live, joinable
session: the visitor has not started co-browsing from the chat widget, or
the previous session already ended. `POST
/api/v1/cobrowse/{conversationId}/control` returns the same code when no
live session exists.

Remedy ladder:

1. Ask the visitor to start co-browsing from the chat widget — joining is
   only possible after the visitor initiates.
2. Re-issue the join request once the session exists; on an already-active
   session the join endpoint is idempotent, so retrying is safe. If control
   packets come back with `403 COBROWSE_CONTROL_NOT_GRANTED` after a
   successful join, the visitor joined observe-only — a consent ceiling,
   not a stuck session.
3. If the visitor ended the session (or either side ended it), the visitor
   must re-initiate from the widget — an `ended` session can never be
   joined again.

Check the join body first-hand: a malformed `conversationId` or body is
refused with `422 VALIDATION_ERROR` before the active-session check runs,
so fix the body before treating the session as missing.

### The frame won't load — CSP / X-Frame-Options blocks embedding

When your operator UI embeds the co-browse viewer and the customer page is
embedded in return, either frame can be refused by the browser: the
customer site sends an `X-Frame-Options: DENY` or `SAMEORIGIN` header, or
its `Content-Security-Policy` `frame-ancestors` directive excludes your
origin, and the embedded view never renders.

Remedy ladder:

1. Relax the frame policy on the page being embedded — remove
   `X-Frame-Options`, or add your origin to the CSP `frame-ancestors`
   directive so the site is embeddable where the session runs.
2. Serve the viewer directly (no wrapper iframe) when the customer's own
   site policy cannot change.
3. Confirm with the page's owner which relaxation is acceptable — frame
   policy sits on the customer's site, and the choice between it and an
   unframed viewer is their call.

### The session starts, then freezes — an edge PoP dropped the data-channel socket

A session can join successfully and then freeze with no further DOM
updates when the closest edge point-of-presence drops the data-channel
(WebSocket) socket. Symptom: the join returned `active`, then nothing
moves.

Remedy ladder:

1. Reconnect the room with the client SDK — it re-mints the join token by
   calling the join endpoint again, which is idempotent on an already-active
   session.
2. Treat the reconnect as routine, not as an error — a token good for 30
   minutes is safe to re-mint, and `started_at` is not reset on re-join.
3. If reconnects flap constantly, check that an intermediate proxy is not
   terminating long-lived WebSockets on an idle timeout.

### Guided control or a custom-tool dispatch returns 502 — the 1 MB ceiling

Co-browse action requests — a guided-control packet, or a custom tool an
agent invokes during the session — travel over the data channel as a
dispatch payload. A payload over the 1 MB ceiling is refused with a 502:

* `POST /api/v1/cobrowse/{conversationId}/control` can return
  `502 COBROWSE_CONTROL_FAILED` when the packet could not be delivered.
* A custom-tool executor whose response body exceeds the 1 MB cap returns
  `CUSTOM_TOOL_RESPONSE_TOO_LARGE` (502).

Remedy ladder:

1. Trim the control packet — shorten the selector and the `value` so the
   serialized body fits well under 1 MB.
2. Paginate or trim large custom-tool response bodies at the executor
   instead of returning one unbounded payload.
3. Note that `502 COBROWSE_CONTROL_FAILED` is a distinct code from
   `CUSTOM_TOOL_RESPONSE_TOO_LARGE`; the first covers delivery of control
   packets into the room, the second covers a custom-tool executor's
   response size. Both share the same remedy — a smaller body.

## Reading errors from the activity feed

When the HTTP verdict alone doesn't pin the stage, read the operator
activity feed on the conversation. `GET /api/v1/conversations/{id}/activity`
returns the activity stream — status changes, assignments, and errors
recorded on the thread — which shows where the co-browse attempt stalled.
See the [Conversations API](/api-reference/conversations) for the endpoint
contract. Match what the feed recorded against the symptom classes above:
no joinable session, a frame-policy block, a dropped socket, or an
oversized dispatch payload.

## See also

* [Co-browse API](/api-reference/cobrowse) — the full session, privacy, and
  control workflow this page diagnoses.
* [Conversations API](/api-reference/conversations) — the activity feed
  endpoint for reading session errors.
* [FAQ: Why did my co-browse session fail to start or leave the customer
  stuck?](/reference/faq#why-did-my-co-browse-session-fail-to-start-or-leave-the-customer-stuck)
  — the short-entry version of this page.
* [Error codes](/reference/error-codes) — the full `COBROWSE_*` and
  `CUSTOM_TOOL_RESPONSE_TOO_LARGE` codes this page works from.
