Skip to main content

API Errors

Since the Tinfoil SDK wraps the OpenAI client, standard API errors (AuthenticationError, RateLimitError, etc.) pass through unchanged. The SDK re-exports them so you can import and catch them directly. See the OpenAI error documentation for details.
import { TinfoilAI, AuthenticationError } from "tinfoil";

const client = new TinfoilAI({
  apiKey: "tk_invalid_key",
});

try {
  await client.chat.completions.create({
    model: "<MODEL_NAME>",
    messages: [{ role: "user", content: "Hello!" }],
  });
} catch (err) {
  if (err instanceof AuthenticationError) {
    console.error("Invalid API key:", err.status, err.message);
  }
}

Client Errors

Tinfoil SDKs do more than just forwarding requests. They also verify attestations, pin certificates, and encrypt payloads before any data leaves your machine. This means you may encounter client-side errors related to attestation and security in addition to the usual server errors from the API. The SDK exposes typed errors so you can catch these failures and recover gracefully.
TinfoilError (base)
├── ConfigurationError  — Client misconfigured
├── FetchError          — Couldn't fetch attestation materials
└── AttestationError    — Attestation verification failed
All errors extend TinfoilError, which extends the native Error class. Each error includes a message string and an optional cause property containing the underlying error.
ErrorCauseWhat to do
ConfigurationErrorBad or missing client optionsFix your code. Retrying will not help.
FetchErrorNetwork issue fetching attestation bundleCall ready() again to retry.
AttestationErrorAttestation verification failedCall reset() then ready().
Thrown when the client is set up incorrectly. Common causes:
  • Missing required options (serverURL, configRepo, apiKey)
  • Invalid option values
  • Using the wrong client type for your environment
  • Calling methods before the client is ready
This error indicates a code-level problem. No amount of retrying will fix it — update your configuration and create a new client instance.
Thrown when the SDK cannot retrieve attestation materials from the attestation transparency cache (ATC). Common causes:
  • Network unreachable or DNS failure
  • HTTP errors (404, 500, etc.)
  • Response timeout
  • Malformed response (bad JSON, unexpected schema)
These failures are usually transient. The SDK automatically clears its internal initialization promise on failure, so calling ready() again will make a fresh attempt.
Thrown when attestation verification fails. This is a security-relevant error. Common causes:
  • Malformed attestation report or invalid encoding
  • Sigstore signature verification failure
  • Hardware certificate chain invalid
  • Attestation report signature invalid
  • Measurement mismatch (enclave code does not match the signed release)
  • Policy violation (e.g. debug mode enabled, TCB level too low)
  • Key binding mismatch (transport keys do not match attested keys)
When you encounter an AttestationError, call reset() to discard the current attestation state, then ready() to fetch and verify a fresh bundle. If the error persists, it may indicate a genuine security issue with the endpoint.
import {
  TinfoilAI,
  ConfigurationError,
  FetchError,
  AttestationError,
} from "tinfoil";

try {
  await client.ready();
} catch (err) {
  if (err instanceof FetchError) {
    // Transient — just retry
    await client.ready();
  } else if (err instanceof AttestationError) {
    // Security issue — need fresh bundle
    client.reset();
    await client.ready();
  } else if (err instanceof ConfigurationError) {
    // Fix your config and create a new client
  }
}

Accessing the Underlying Cause

All errors support the standard cause property. When the SDK wraps a lower-level error, the original is available for debugging:
try {
  await client.ready();
} catch (err) {
  if (err instanceof FetchError) {
    console.error("Fetch failed:", err.message);
    console.error("Caused by:", err.cause);
  }
}
At the transport layer, HPKE and key-related errors trigger an automatic reset-and-retry once before surfacing to your code.