---
sidebar_position: 12
---

# Errors

Every refusal has a short code. The page hands it on as `code` (`e.code` of a rejected promise, `{ code }` of an `error` or `realtime:error` event, a call's `endReason`); PHP returns it as a `WP_Error`'s code.

## The connection

`rt.on( 'error', ( e ) => … )`: the realtime server refused the page's connection.

| Code | Why | What to do |
|---|---|---|
| `not_licensed` | the server doesn't know the site key | the site's credentials are wrong or revoked: activate a WordPlus plugin's licence again, or connect again |
| `not_included` | the site's plan doesn't include realtime | upgrade the plan in the WordPlus Cloud account |
| `wrong_origin` | the page isn't on the site's licensed address (with or without `www.`) | serve the page from the site's address; a headless front end on another domain isn't supported |
| `over_capacity` | a staging copy has its 25 people online | expected on a staging copy |
| `try_later` | a server still starting | the page tries again by itself |
| `bad_request` | the handshake was malformed | |

## Channels

`realtime:error` on a subscription:

| Code | Why |
|---|---|
| `forbidden` | the channel's owner said no, or no plugin owns it |
| `expired`, `bad_token` | the token ran out, or wasn't signed by the site (the page asks again once for an expired one) |
| `bad_channel` | not a channel name the server takes |
| `too_many` | the connection holds 1,000 channels |
| `full` | a presence channel has its 1,000 members |
| `auth_failed` | the site's auth route didn't answer |
| `not_connected` | the site has no credentials |
| `no_auth` | the page has no auth route |
| `timeout`, `server` | the server didn't answer, or failed |

`trigger()` also rejects with `rate_limited` (over 10 a second), `bad_event` (not `client-…`), `too_large` (over 10 KB), or `forbidden` (a public channel, or one the tab doesn't hold).

## Publishing

`publish()`, `publish_batch()` and `channel_info()` return a `WP_Error`:

| Code | Why |
|---|---|
| `not_connected` | the site has no credentials |
| `missing_signature`, `stale_signature`, `unknown_site`, `bad_signature` | the request's signature wasn't taken: a site clock off by more than 5 minutes is `stale_signature` |
| `not_included` | the plan doesn't include realtime |
| `bad_request` | no channels, or an event named `realtime:…` |
| `too_many`, `too_large` | over 100 channels or 10 events, or data over 10 KB |
| `http_<status>`, or WordPress's own | the server couldn't be reached |

## Calls

From `calls.start()`, `incoming.accept()` and `calls.room()` (rejected with `code`), from the calls route (`denied`), and as a call's `endReason` when the server refused to start it:

| Code | Why |
|---|---|
| `forbidden` | your `calls()` callback said no, or no plugin owns the call |
| `no_user` | nobody to call as: a visitor without an id ([calls](calls.md#visitors)) |
| `not_included` | the plan doesn't include calls |
| `bad_request` | a call or room name the server doesn't take, or calling yourself |
| `bad_token`, `expired` | the token wasn't the site's, or ran out |
| `no_call`, `call_ended` | answered after the caller gave up |
| `answered_elsewhere` | answered on another device |
| `not_connected` | the site has no credentials |
| `auth_failed`, `no_auth` | the site's calls route didn't answer, or the page has none |
| `no_media` | the server has no media servers set up |
| `no_rooms_script`, `rooms_script_failed`, `rooms_script_broken` | the media client's script isn't there, or didn't load |
| `signaling_unavailable` | the page's connection was down |

`decline()` rejects with `answered` when the call was already answered on another device.

How a call ended is in [calls](calls.md#why-a-call-ended).
