Athos Developer Docs
Browser SDK

Error codes

The SDK error taxonomy and how to handle each failure.

Errors surface two ways, and you should handle both:

  • as an error event — session.on('error', ({ code, message }) => …);
  • as a rejected promise from connect() — await session.connect().catch(…).

Always branch on code. message is human-readable and may change — never parse it. The full runtime list is exported as ATHOS_ERROR_CODES.

import { AthosRoleplayError } from '@useathos/sdk';

session.on('error', ({ code, message }) => {
  switch (code) {
    case 'MIC_PERMISSION_DENIED': return promptForMicAccess();
    case 'AUDIO_PLAYBACK_BLOCKED': return showResumeButton();
    case 'NETWORK_LOST': return offerRestart();
    default: console.error(code, message);
  }
});

try {
  await session.connect();
} catch (e) {
  // A caught value is `unknown` under strict TypeScript. `AthosRoleplayError` narrows it so
  // you can read `.code` — anything else is not from the SDK, so rethrow it.
  if (e instanceof AthosRoleplayError) showStartFailed(e.code);
  else throw e;
}

Codes the SDK emits

These originate in the browser at runtime:

CodeMeaning
MIC_PERMISSION_DENIEDThe user denied microphone permission.
MIC_DEVICE_DISCONNECTEDThe active microphone was unplugged, or is held by another app.
NO_MIC_AVAILABLENo microphone is available, or the page is not served over HTTPS.
NETWORK_LOSTThe connection dropped and could not recover within 30s. The session ended.
AUDIO_PLAYBACK_BLOCKEDThe browser blocked audio autoplay; call resumeAudio() from a user gesture.
BROWSER_NOT_SUPPORTEDSafari / mobile / unsupported browser (thrown synchronously from create()).
SESSION_ALREADY_CONNECTEDconnect() was called twice on the same session — sessions are single-use; create a new one per call.

connect() asks for the microphone before it redeems the token, so a denied or missing microphone normally leaves the token unspent. Recover by fixing the device and retrying the same token on a new session (always create a new session per attempt); if that returns TOKEN_ALREADY_USED, the failure came from later in the call setup — mint a fresh token. See Microphone & audio.

Codes from the session redemption

When connect() redeems the token, the server may reject it. These surface through the same error channel:

CodeMeaningWhat to do
INVALID_TOKENThe token was malformed or rejected.Mint a fresh token.
TOKEN_EXPIREDThe token's ~5-minute lifetime elapsed before connecting.Mint at "start" click, not page load.
TOKEN_ALREADY_USEDThe single-use token was already redeemed.Mint a new token per call.
DRILL_NOT_FOUNDThe drillKey doesn't match a known drill.Check the Drills reference, then mint a new token — this attempt spent it.
INVALID_REQUESTThe request was invalid (e.g. blank drillKey).Fix the create() options. The token is unspent, so the same one still works.
SERVICE_UNAVAILABLENo persona is available for the drill right now — the only 503; an infrastructure failure is INTERNAL_ERROR.Mint a new token and start a new call — the token is spent.
INTERNAL_ERRORAn unexpected error.Mint a new token and start a new call; if it persists, contact Athos with the message.

A failed redemption usually spends the token — most of the failures above need a newly minted token, not a replay. Which ones leave it unspent: error reference.

The other nine codes in ATHOS_ERROR_CODES — INVALID_API_KEY, API_KEY_REVOKED, IP_NOT_ALLOWED, TENANT_INACTIVE, TENANT_QUOTA_EXCEEDED, CALL_NOT_FOUND, AGENT_NOT_FOUND, AGENT_ALREADY_EXISTS and AGENCY_NOT_FOUND — never reach the browser. They come back on your backend's server-to-server calls (for example AGENT_NOT_FOUND and TENANT_QUOTA_EXCEEDED when you mint a token for an unregistered rep or once the allowance is spent), so handle them there, not on the SDK's error channel. The full table is the error reference.

The token-lifecycle codes (INVALID_TOKEN, TOKEN_EXPIRED, TOKEN_ALREADY_USED) almost always trace back to when you mint the token. Mint it the instant the rep clicks "start practice", use it once, and let it expire — see Authentication.

On this page