TypeScript client

Handle client errors

Classify TypeScript client failures and recover safely from sign-in and session errors.

Most client operations return expected failures in { data, error }. Handle the result before using data:

import {
  APIUnboundError,
  AuthUnboundError,
} from "unbound-auth";

const { data: session, error } = await auth.getSession({ verify: true });

if (error instanceof AuthUnboundError) {
  handleAuthFailure(error.code);
} else if (error instanceof APIUnboundError) {
  handleServiceFailure(error.code, error.status);
} else if (error) {
  handleUnexpectedFailure(error);
} else {
  renderSession(session);
}

Do not assume expected auth failures throw. initialize() is an exception to the result pattern and can reject, as can synchronous adapter setup misuse or application event callbacks.

Error classes

ClassMeaningUseful fields
AuthUnboundErrorAuthorization, callback, or token condition the app can classifycode, message
APIUnboundErrorNetwork or unexpected server responsecode, status, cause
UnboundErrorBase package errorcode, message
ErrorUnexpected runtime, adapter, or listener failurename, message

APIUnboundError.code can be NETWORK_ERROR, SERVER_ERROR, or UNKNOWN. Network failures can include unavailable fetch, invalid JSON, and other request-time failures.

Start errors

CodeCauseResponse
MISSING_REDIRECT_URINo valid callback can be resolvedConfigure an HTTP(S) callback; servers need an absolute URL
MISSING_SCOPESNo supported scopes remainRequest at least one of openid, profile, or email
Other ErrorWeb Crypto, URL, or storage failedFix runtime/storage access before retrying
const { data, error } = await auth.startSignIn();

if (error) {
  showSignInError(error);
} else {
  window.location.assign(data.url);
}

The callback belongs on a separate page or route after authorization server navigation.

Callback errors

CodeTypical causeSafe recovery
MISSING_CODECallback has no authorization codeStart a fresh sign-in
MISSING_STATECallback has no stateStart a fresh sign-in
INVALID_STATEReturned state differs from stored stateReject the callback and restart
MISSING_VERIFIERPending PKCE verifier was lostRestart in the same tab/storage context
INVALID_VERIFIERVerifier does not match the code challengeReject and restart
INVALID_CODECode is malformed or cannot be acceptedRestart; do not reuse it
EXPIRED_CODECallback code exceeded its lifetimeStart a fresh sign-in
USED_CODEThe server recorded prior code useStart a fresh sign-in
INVALID_REDIRECT_URIExchange callback differs from authorization callbackCorrect configuration, then restart
INVALID_CLIENT_IDCallback origin/client binding differsCorrect origin configuration, then restart

Security requirement

Never ignore a state mismatch. Server flows and browser flows that pass code explicitly must compare returned state against application-stored state before calling finishSignIn().

Authorization denial currently arrives as error=access_denied, and the browser client does not parse it as a dedicated callback error. Because denial may omit state, finishSignIn() commonly reports MISSING_STATE or MISSING_CODE. Detect error=access_denied on the callback page when you need a specific cancellation message, discard pending flow state, and offer a new start.

Token and session errors

CodeMeaningResponse
MISSING_TOKENsetSession() received no tokenRequire a non-empty trusted token
INVALID_TOKENToken is malformed or /userinfo rejected itClear application state and sign in again
EXPIRED_TOKENToken expiration passedStart sign-in again

A browser decode-only result is not proof of token authenticity. Use getSession({ verify: true }) to check through /userinfo, or validate tokens with the trust checks required by your server architecture.

When an initialized session becomes invalid, the client clears its in-memory session and can emit logout with expired or revoked. The stored token may remain, so custom recovery may need to replace storage or begin a clean authorization flow.

Network and server errors

  • NETWORK_ERROR covers fetch, response parsing, and unexpected request-time failures.
  • SERVER_ERROR covers non-success responses that do not map to a known auth code and malformed successful /userinfo data.
  • status is available when an HTTP response supplied one.
  • Unexpected server failures are not guaranteed to return JSON.

Retry transient network failures with bounded backoff only when the operation is safe. A callback code may already have been exchanged even if the client did not receive the response.

Retry safely

  • Restart sign-in after missing, invalid, expired, or used callback data.
  • Never reuse a successful callback URL or authorization code.
  • Do not run manual and automatic callback completion together.
  • Consume server-side pending state once, including on rejected callbacks.
  • Preserve error codes for user-facing mapping, but do not display tokens, codes, verifiers, cookies, or raw sensitive server responses.
  • Treat uncertain callback exchange outcomes as non-retryable with the same code; begin a new flow.

For complete recovery placement, see the browser callback flow and server callback route.

On this page