# Auth0 Auth JS Error Classes and OAuth2Error Wrapping: A Complete Guide

> Explore Auth0 Auth JS error classes and how the SDK wraps OAuth2Error. Understand error codes and access the raw OAuth 2.0 error payload for complete observability.

- Repository: [Auth0/auth0-auth-js](https://github.com/auth0/auth0-auth-js)
- Tags: deep-dive
- Published: 2026-02-25

---

**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`](https://github.com/auth0/auth0-auth-js/blob/main/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:

```typescript
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 original `OAuth2Error` payload from the Authorization Server, preserving the `error`, `error_description`, and optional `message` fields.

### 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`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/errors.ts):

```typescript
export interface OAuth2Error {
  error: string;
  error_description: string;
  message?: string;
}

```

### Error Wrapping Pattern

In [`packages/auth0-auth-js/src/auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/auth-client.ts), every public method follows a consistent pattern. For example, `buildAuthorizationUrl` implements:

```typescript
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:

```typescript
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:

```typescript
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:

```typescript
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`](https://github.com/auth0/auth0-auth-js/blob/main/packages/auth0-auth-js/src/errors.ts), all extending the abstract `ApiError` base class.
- Every API error exposes a **stable `code` string** (e.g., `token_by_code_error`) for programmatic error handling.
- Raw OAuth 2.0 errors from the Authorization Server are **preserved in the `cause` property**, which implements the `OAuth2Error` interface with `error`, `error_description`, and optional `message` fields.
- Public methods in [`auth-client.ts`](https://github.com/auth0/auth0-auth-js/blob/main/auth-client.ts) wrap underlying `openid-client` failures using a consistent try-catch pattern, converting raw errors into domain-specific classes like `TokenExchangeError` or `BuildAuthorizationUrlError`.

## 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`](https://github.com/auth0/auth0-auth-js/blob/main/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.