Auth0 Auth JS Error Classes and OAuth2Error Wrapping: A Complete Guide
The Auth0 Auth JS SDK exposes a hierarchy of domain-specific error classes that extend ApiError, each exposing a stable code string and preserving the raw OAuth 2.0 error payload in a cause property for full observability.
The auth0/auth0-auth-js repository provides a TypeScript SDK for OAuth 2.0 and OpenID Connect flows. When API calls fail, the SDK does not surface raw HTTP responses or generic Error objects. Instead, it normalizes every failure into strongly-typed error classes while preserving the original server-side error details for debugging and user-facing messages.
Error Class Hierarchy in auth0-auth-js
All error classes are defined in packages/auth0-auth-js/src/errors.ts. The architecture separates API-related failures from configuration or validation errors.
The ApiError Base Class
The abstract ApiError class serves as the foundation for all OAuth 2.0 flow failures:
abstract class ApiError extends Error {
public cause?: OAuth2Error;
public code: string;
// ...
}
code: A machine-readable string that uniquely identifies the error type (e.g.,token_by_code_error).cause: Stores the originalOAuth2Errorpayload from the Authorization Server, preserving theerror,error_description, and optionalmessagefields.
Concrete Error Classes
The SDK defines specific subclasses for every failure mode in the authentication lifecycle:
| Error Class | Code Value | Thrown When |
|---|---|---|
TokenByCodeError |
token_by_code_error |
getTokenByCode fails during authorization code exchange |
TokenByClientCredentialsError |
token_by_client_credentials_error |
Client credentials flow fails |
TokenByRefreshTokenError |
token_by_refresh_token_error |
Refresh token exchange fails |
TokenExchangeError |
token_exchange_error |
RFC 8693 token exchange or Token Vault flows fail |
TokenForConnectionError |
token_for_connection_error |
Legacy getTokenForConnection fails (backward-compatibility wrapper) |
BuildAuthorizationUrlError |
build_authorization_url_error |
Authorization URL construction fails, including Pushed Authorization Requests (PAR) |
BuildLinkUserUrlError |
build_link_user_url_error |
Link-user URL construction fails |
BuildUnlinkUserUrlError |
build_unlink_user_url_error |
Unlink-user URL construction fails |
BackchannelAuthenticationError |
backchannel_authentication_error |
CIBA flow initiation, polling, or grant fails |
VerifyLogoutTokenError |
verify_logout_token_error |
Back-channel logout token validation fails |
MissingClientAuthError |
missing_client_auth_error |
No client authentication method is configured |
NotSupportedError |
Varies | Feature not supported (e.g., PAR disabled, mTLS without custom fetch) |
All classes extending ApiError inherit the cause property, allowing access to the raw OAuth 2.0 error response.
How the SDK Wraps OAuth2Error Exceptions
The SDK uses openid-client for underlying HTTP calls. When that library throws, the SDK assumes the object conforms to the OAuth2Error interface and wraps it in a domain-specific class.
The OAuth2Error Interface
Raw errors from the Authorization Server match this structure, defined in packages/auth0-auth-js/src/errors.ts:
export interface OAuth2Error {
error: string;
error_description: string;
message?: string;
}
Error Wrapping Pattern
In packages/auth0-auth-js/src/auth-client.ts, every public method follows a consistent pattern. For example, buildAuthorizationUrl implements:
try {
return await this.#buildAuthorizationUrl(options);
} catch (e) {
// e is expected to be an OAuth2Error from openid-client
throw new BuildAuthorizationUrlError(e as OAuth2Error);
}
The constructor of the specific error class forwards the OAuth2Error to the ApiError base class, which stores it in this.cause. This preserves the full server response while providing a stable SDK error type.
Accessing the Original Error
Consumers can inspect both the SDK error classification and the underlying OAuth 2.0 failure:
try {
await authClient.buildAuthorizationUrl(opts);
} catch (err) {
if (err instanceof BuildAuthorizationUrlError) {
console.error('SDK error code:', err.code);
console.error('OAuth2 error:', err.cause?.error);
console.error('Description:', err.cause?.error_description);
}
}
Practical Error Handling Examples
Handling Token Exchange Failures
When performing RFC 8693 token exchanges:
import { AuthClient, TokenExchangeError } from '@auth0/auth0-auth-js';
const client = new AuthClient({
domain: 'my-tenant.auth0.com',
clientId: 'YOUR_CLIENT_ID',
clientSecret: 'YOUR_CLIENT_SECRET',
});
(async () => {
try {
const resp = await client.exchangeToken({
connection: 'google-oauth2',
subjectToken: 'bad-token',
});
console.log('Token:', resp.accessToken);
} catch (err) {
if (err instanceof TokenExchangeError) {
console.error('Exchange failed – code:', err.code);
console.error('OAuth error:', err.cause?.error);
console.error('Details:', err.cause?.error_description);
} else {
console.error('Unexpected error:', err);
}
}
})();
Validating Logout Tokens
When verifying back-channel logout tokens:
import { AuthClient, VerifyLogoutTokenError } from '@auth0/auth0-auth-js';
(async () => {
try {
const result = await client.verifyLogoutToken({
logoutToken: 'invalid.jwt.token'
});
console.log('Logout token valid for SID:', result.sid);
} catch (err) {
if (err instanceof VerifyLogoutTokenError) {
console.error('Logout token verification failed –', err.message);
console.error('Error code:', err.code);
}
}
})();
Summary
- The Auth0 Auth JS SDK defines a hierarchy of error classes in
packages/auth0-auth-js/src/errors.ts, all extending the abstractApiErrorbase class. - Every API error exposes a stable
codestring (e.g.,token_by_code_error) for programmatic error handling. - Raw OAuth 2.0 errors from the Authorization Server are preserved in the
causeproperty, which implements theOAuth2Errorinterface witherror,error_description, and optionalmessagefields. - Public methods in
auth-client.tswrap underlyingopenid-clientfailures using a consistent try-catch pattern, converting raw errors into domain-specific classes likeTokenExchangeErrororBuildAuthorizationUrlError.
Frequently Asked Questions
What is the base class for all API errors in Auth0 Auth JS?
The abstract ApiError class defined in packages/auth0-auth-js/src/errors.ts serves as the base for all API-related errors. It extends the native JavaScript Error class and adds a code property for machine-readable error identification and an optional cause property that stores the original OAuth2Error from the Authorization Server.
How can I access the original OAuth 2.0 error description when catching SDK errors?
Access the cause property on any caught error that extends ApiError. The cause object implements the OAuth2Error interface and contains error (the OAuth error code), error_description (the human-readable explanation), and an optional message field. For example: err.cause?.error_description.
Which error class is thrown when the authorization URL fails to build?
The SDK throws BuildAuthorizationUrlError when constructing the authorization URL fails, including during Pushed Authorization Requests (PAR). This error has the code build_authorization_url_error and will contain the underlying OAuth 2.0 error in its cause property if the failure originated from the Authorization Server.
Does Auth0 Auth JS throw different errors for each token endpoint flow?
Yes. The SDK provides distinct error classes for each token acquisition method: TokenByCodeError for authorization code exchanges, TokenByClientCredentialsError for client credentials, TokenByRefreshTokenError for refresh token flows, and TokenExchangeError for RFC 8693 token exchanges. Each class has a unique code string identifying the specific flow that failed.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →