Errors
Failures to join reject with AvatarGoError:
import { AvatarGoError } from "@avatargo/sdk";
try {
await client.streamToVideoElement("avatar");
} catch (e) {
if (e instanceof AvatarGoError) console.log(e.code, e.status, e.message);
}code is stable — branch on it; message is for people and may change.
A listener (client.on(…)) that throws does not stop the other listeners of that event, nor the
tool call the event told of; the error is written to the console.
code | status | Means | What to do |
|---|---|---|---|
unauthorized | 401 | The session token is missing, malformed or expired (tokens last one hour). | Get a new token from your server. |
not_found | 404 | No such session. | Create a new one. |
session_ended | 410 | The session is already over. | Create a new one — a session that is over cannot be joined again. (While it is live, joining again with its token rejoins it.) |
quota_exceeded | 402 | Your account’s credit would not last a minute of every call it has going plus this one (checked again when the user joins; the session has failed). | Top up, or turn on automatic top-up, in the console; then create a new session. |
concurrency_limit | 429 | Your plan’s calls at once are all going; the session has failed. | Wait for a call to end, or upgrade; then create a new session. |
forbidden | 403 | Your account is on hold over a payment; the session has failed. | Contact support. |
connection_failed | 0 | The room could not be joined. | Say so; offer a retry. |
microphone_unavailable | 0 | The room was joined, but the microphone could not be turned on: the user refused permission, or there is none. The SDK has left the room again. | Say so; offer { microphone: false } with a new session, or a retry. |
session_ended | 0 | This client’s session is already over (stopStreaming() or endSession() was called, or it ended) and a client is for one session. | Create a new client with a new session token. |
internal_error | 500 | Something failed in AvatarGo. | Retry with a new session. |
talk(), addContext() and sendUserMessage() reject with these, all with status 0:
code | Means | What to do |
|---|---|---|
not_streaming | Not in a session: before streamToVideoElement resolved, or after it ended. | Join first. |
client_controls_disabled | The session was created without sessionOptions.clientControls: true, or it is avatar only. | Switch it on on your server, or send it from there (POST /v1/sessions/{id}/talk, /context). |
invalid_request | text is blank or too long. | Send 1–4,000 characters (talk), 1–8,000 (addContext) or 1–2,000 (sendUserMessage). |
session_not_live | The character is not ready yet (it joins just before the avatar appears). | Wait for video_play_started, or retry shortly. |
rate_limited | More than 20 talk (or 20 addContext, or 20 sendUserMessage) in the last minute for this session, your server’s included. | Wait; the message says how long. |
Treat codes you do not know as internal_error. Refusals when creating a session — no
capacity (concurrency_limit), not enough credit (quota_exceeded), the avatar not ready, a model
unavailable, a character that is not published (character_not_published) — come to your server from
POST /v1/auth/session-token, before the page is involved; see the API reference. Your plan and
credit are judged once more when the user joins, as they may have changed since the token: that is
where quota_exceeded, concurrency_limit and forbidden above come from.