Errors
Master reference for every error code the SDK can surface. Each error follows the SDKError shape (code / message / kind / retriable?) and is delivered through one of the SDK's existing channels: Promise rejection or event payload. Codes are stable strings; switch on err.code for specific handling, or err.kind for grouped recovery.
- Promise rejection โ methods that return a Promise reject with an
SDKErrorwhen they fail (e.g.VideoSDK.join(),me.publishVideo()). The Promise is the natural error channel for explicit calls. - Event payload โ for failures that happen async (no Promise to reject), the SDK fires an event with the error in the payload (e.g.
me.on('stream-publish-failed', { kind, error })).
Error shape
See types.html โ SDKError for the full type definition with examples (generic retry helper, categorical handler).
By surface โ where each code can fire
Codes are scoped to the surface that produces them. The same code may fire on multiple surfaces (e.g. CAMERA_IN_USE can come from both an explicit publishVideo() rejection and an async stream-publish-failed event).
VideoSDK.join() โ Promise rejection
Fired when the join handshake fails. 21 codes. See VideoSDK.join.
| code | kind | retriable | When | v0 |
|---|---|---|---|---|
INVALID_API_KEY | Auth | false | API key revoked or never valid | 4001 |
INVALID_TOKEN | Auth | false | Token missing / malformed / expired | 4002 |
INVALID_PERMISSIONS | Auth | false | Token's permissions claim is wrong | 4008 |
UNAUTHORIZED_ROOM | Auth | false | Token not authorized for this roomId | 4022 |
UNAUTHORIZED_PARTICIPANT | Auth | false | Token not authorized for this participantId | 4023 |
INVALID_ENTRY_CLAIM | Auth | false | Token's joinPolicy is invalid โ mode: 'ask' with canModerate, ttl set with mode: 'direct', or ttl outside 10..600. Primary path: backend helper throws at mint time (no JWT created); server re-validates as a safety net for hand-rolled JWTs. | โ |
ENTRY_DENIED | Auth | false | A moderator clicked Deny on this joiner's lobby request. | โ |
ENTRY_TIMEOUT | Auth | true | Server ttl fired before any moderator decided. Retry permitted within the rate-limit window. | โ |
ENTRY_RATE_LIMITED | Auth | true | Too many lobby attempts on the same token (default 3 per 5 minutes). Retry after the window. | โ |
INVALID_ROOM_ID | Config | false | Room ID malformed / missing | 4003 |
INVALID_PARTICIPANT_ID | Config | false | Bad participantId shape in JoinOptions | 4004 |
INVALID_PROTOCOL_PREFERENCE | Config | false | preferredProtocol: UdpOnly requested but not available | โ |
CONFLICTING_PUBLISH_CONFIG | Config | false | Both pre-call stream AND JoinOptions.publishVideo set for same kind | โ |
STREAM_ALREADY_EXISTS | Config | false | Pre-call singleton conflict | โ |
ROOM_FULL | Server | true | Max participants reached | 4009 |
DUPLICATE_PARTICIPANT | Server | false | Same participantId already in room | 4005 |
ACCOUNT_DEACTIVATED | Server | false | Organization account deactivated | 4006 |
ACCOUNT_DISCONTINUED | Server | false | Organization account discontinued | 4007 |
NETWORK_ERROR | Network | true | Signaling unreachable / connection refused / ICE / DTLS โ SDK has retried internally; this is the give-up | โ |
TIMEOUT | Network | true | Overall join handshake exceeded SDK timeout | โ |
BROWSER_UNSUPPORTED | Config | false | WebRTC unavailable in this runtime | 3011/3012 |
me.on('stream-publish-failed', { kind, error }) โ event payload
Fired when any local publish fails โ initial attempt OR mid-call runtime failure of a previously-live stream. 14 codes. See LocalParticipant events. After this event, me.<kind> is null.
Initial publish failures โ capture / negotiation / acquisition. Also surface as Promise rejection on explicit me.publishVideo({}) calls.
| code | kind | retriable | When | v0 |
|---|---|---|---|---|
CAMERA_IN_USE | Media | true | Another app holds the camera | 3023 |
MICROPHONE_IN_USE | Media | true | Another app holds the mic | 3024 |
CAMERA_NOT_FOUND | Media | true | No camera connected | 3021 |
MICROPHONE_NOT_FOUND | Media | true | No mic connected | 3022 |
MEDIA_PERMISSION_DENIED | Permission | false | User blocked the permission prompt | 3014/3015/3017/3018 |
INVALID_DEVICE | Media | false | Passed device no longer exists (e.g. unplugged just before publish) | โ |
CONSTRAINT_FAILED | Media | true | Resolution / framerate not supported by selected device | โ |
Mid-call runtime failures โ fire when a previously-live stream dies. Stream is gone after the event; me.<kind> becomes null. App can retry via me.publishVideo({}).
| code | kind | retriable | When | v0 |
|---|---|---|---|---|
CAMERA_DEVICE_LOST | Media | true | Camera unplugged / disconnected mid-call | 3027 |
MICROPHONE_DEVICE_LOST | Media | true | Mic unplugged / disconnected mid-call | 3028 |
CAMERA_PERMISSION_REVOKED | Permission | false | OS revoked camera permission mid-call | โ |
MICROPHONE_PERMISSION_REVOKED | Permission | false | OS revoked mic permission mid-call | โ |
SCREEN_SHARE_STOPPED | Media | true | User clicked browser's "Stop sharing" button | โ |
ENCODER_FAILED | Media | true | Video / audio encoder died | โ |
TRACK_ENDED | Media | true | Generic โ track ended for unknown reason | โ |
room.pubsub.publish() โ Promise rejection
Errors that can reject the publish Promise. SDK-local errors (no round trip) listed first.
| code | origin | kind | retriable | cause |
|---|---|---|---|---|
INVALID_TOPIC_NAME | SDK | Config | false | Topic violates naming rules (1โ128 chars from [a-zA-Z0-9_-:.]) |
PAYLOAD_TOO_LARGE | SDK | Config | false | Payload > 32 KiB after JSON encoding |
INVALID_PAYLOAD | SDK | Config | false | Payload not JSON-serializable (circular ref, BigInt, Function, etc.) |
NOT_CONNECTED | SDK | Network | false | Publish called before join or after leave |
RATE_LIMIT_EXCEEDED | Server | Network | true | Per-topic publish rate exceeded (server policy) |
PERMISSION_DENIED | Server | Permission | false | Topic restricted for this client by server policy |
NETWORK_ERROR | SDK/Server | Network | true | Transient connection issue; SDK auto-retries 3ร with backoff before rejecting |
NETWORK_ERROR with an internal idempotency key โ no duplicate messages even if multiple retries reach the server. App sees one final Promise resolve / reject.Service start / stop โ Promise rejection
Errors that can reject the start / stop methods for room server-side services โ startRecording / stopRecording, startHls / stopHls, startLivestream / stopLivestream, startTranscription / stopTranscription. 2 codes. Both are SDK-local guard rejections โ raised before any wire call when the service is not in a valid state for the requested transition. State is read from the matching ServiceState getter (recordingState / hlsState / livestreamState / transcriptionState).
| code | origin | kind | retriable | cause |
|---|---|---|---|---|
ALREADY_STARTED | SDK | Server | false | A start method was called while the service is not in a startable state. A service is startable only from ServiceState.Stopped or ServiceState.Failed; calling start while it is starting / started / stopping rejects with this code. |
NOT_STARTED | SDK | Server | false | A stop method was called while the service has nothing to stop. Stop is valid only from ServiceState.Starting or ServiceState.Started; calling stop while it is stopped / failed / stopping rejects with this code. |
p.subscribe() / p.unsubscribe() โ Promise rejection
Errors that can reject subscribe / unsubscribe on a RemoteParticipant. Subscribe targets a kind on a specific participant; rejections cover the four failure modes (state, permission, identity, network).
| code | kind | retriable | cause |
|---|---|---|---|
NOT_PUBLISHED | Server | false | The target participant has not published the requested kind (or any one kind in an array โ subscribe arrays are all-or-nothing). Retrying the same call fails identically until the publisher actually publishes; the correct pattern is to subscribe in response to the stream-published event (which fires retroactively for already-published kinds + live for new ones). See RemoteParticipant.subscribe. |
INVALID_PERMISSIONS | Auth | false | Your token's grant lacks canSubscribe, or the target is a viewer-tier participant (isViewer: true) โ viewers don't publish media. See Authentication โ grant. |
PARTICIPANT_NOT_FOUND | Server | false | The participant left between your call and the server ack. |
NETWORK_ERROR | Network | true | Transient connection issue; SDK auto-retries before rejecting. |
NOT_PUBLISHED is the "subscribe before publish" signal. It's not a retry-able fault โ calling subscribe repeatedly until they publish would just hammer the server. Listen to stream-published on the RemoteParticipant instead; that event fires retroactively for already-published kinds AND live for new ones, so a single handler covers the full subscribe lifetime.Other surfaces โ TBD
Inventories for these surfaces will be locked as we complete the corresponding design topics. Each will list its closed code set here.
room.leave()โ Promise rejection codesVideoSDK.runPreCallTest()โ phase errors viaonError+result.errors[]room.setOutputDevice()โ Promise rejection codessetInputDevice()on local streams โ device switch errorspin/unpinon participants โ server-rejection codesroom.pubsub.subscribe()/getHistory()โ to lock with subscribe/history finalization- Recording / livestream / HLS / transcription โ per-feature codes (decision deferred until those features get their own DX pass)
ConnectionEvent.disconnected.causeโ low-level network causes (separate from DisconnectReason)
All codes โ alphabetical
Master cross-reference. Click any code to jump to the full description in its surface section above.