Error Handling

Learn how to handle SDK errors, diagnose common failures, distinguish network issues from API responses, and build resilient wallet workflows.

WalletsApiError

All SDK methods throw WalletsApiError on non-2xx HTTP responses. It extends the native Error class with structured HTTP response data:

import { WalletsApiError } from "@tatumio/wallet-sdk";

try {
  const shares = await client.generateWallet();
} catch (err) {
  if (err instanceof WalletsApiError) {
    console.error(`HTTP ${err.status}: ${err.message}`);
    console.error("Response body:", err.body);
    // err.status     — HTTP status code (number)
    // err.statusText — HTTP status text (string | undefined)
    // err.body       — parsed response body (unknown)
    // err.headers    — response Headers object
  }
}

Common Errors

401 — Invalid API Key

WalletsApiError: Unauthorized

Cause: The apiKey passed to TatumWalletsSdk is invalid or expired.

Fix: Verify your API key at tatum.io. The key goes in apiKey, not as a header — the SDK handles auth headers internally.

403 — Insufficient Permissions

WalletsApiError: Forbidden

Cause: The token used in initClient() doesn't have permission for the requested operation. A Client Session Token can only access that client's data.

Fix: Use clientApiKey for custodian-level operations. Don't use a CST to call custodian endpoints.

404 — Client or Wallet Not Found

WalletsApiError: Not Found

Cause: The clientId or walletId doesn't exist in your custodian environment.

Fix: Verify the ID. IDs from staging environments don't work in production.

422 — Missing Signing Share

WalletsApiError: Unprocessable Entity

Cause: The share passed to sendAssets(), sign(), or rawSign() is invalid or doesn't correspond to the wallet.

Fix: Ensure you're passing the correct curve's share. For EVM chains, use SECP256K1. For Solana/Stellar, use ED25519.

422 — Unsupported Chain

Cause: The chain value is not in WalletChain.

Fix: Use the WalletChain enum rather than raw strings.

422 — Insufficient Funds

Cause: The wallet doesn't have enough balance for the transfer plus gas.

Fix: Check the wallet balance before sending. For gas-free flows, enable sponsorGas: true.

422 — Wallet Feature Disabled

Cause: The operation (e.g. eject) is not enabled for this client's environment.

Fix: Contact Tatum to enable the feature for your custodian environment.

Error Handling Pattern

import { WalletsApiError } from "@tatumio/wallet-sdk";

async function safeSend(client, body) {
  try {
    return await client.sendAssets({ body });
  } catch (err) {
    if (!(err instanceof WalletsApiError)) throw err; // re-throw unexpected errors

    switch (err.status) {
      case 401:
        throw new Error("Authentication failed — check your Tatum API key");
      case 422: {
        const detail = (err.body as any)?.message ?? err.message;
        if (detail.includes("Insufficient")) {
          throw new Error("Insufficient balance for this transfer");
        }
        throw new Error(`Invalid request: ${detail}`);
      }
      case 429:
        throw new Error("Rate limit exceeded — retry after a delay");
      default:
        throw new Error(`Tatum API error (${err.status}): ${err.message}`);
    }
  }
}

Network Errors

If the fetch call itself fails (no response), a standard TypeError is thrown (not a WalletsApiError). Handle it separately:

try {
  await client.generateWallet();
} catch (err) {
  if (err instanceof WalletsApiError) {
    // HTTP error with a response
  } else if (err instanceof TypeError) {
    // Network failure — no response received
    console.error("Network error:", err.message);
  }
}