Atlas
Reference

Error Codes

Complete reference for every error code Atlas returns — server-side chat errors, client-side detection codes, and SDK error handling.

Atlas uses structured error codes across its API, SDK, and chat interface. Every error response includes a code field identifying the failure, a human-readable message, and a retryable flag indicating whether the client should retry.

Error codes are defined in @useatlas/types/errors and shared across all Atlas packages.


Server Error Codes (ChatErrorCode)

These codes are returned by the Atlas API in JSON error responses. Each maps to an HTTP status code and a retryable classification.

Retryable Errors

Transient failures where retrying the same request may succeed. Use exponential backoff for retries.

CodeHTTP StatusDescriptionCommon CauseFix
rate_limited429Too many requestsClient exceeding the per-user rate limitWait for retryAfterSeconds then retry. Reduce request frequency
provider_rate_limit503AI provider rate limitedUpstream LLM provider (Anthropic, OpenAI, etc.) throttling requestsWait and retry with backoff. Consider upgrading your provider plan
provider_timeout504AI provider timed outLLM took too long to respond, or query exceeded ATLAS_QUERY_TIMEOUTRetry with a simpler question. Increase ATLAS_QUERY_TIMEOUT if queries are complex
provider_unreachable503Cannot reach the AI providerNetwork issue between Atlas and the LLM provider, or provider outageCheck provider status page. Retry after a short delay
provider_error502AI provider returned an errorUnexpected error from the LLM provider (500, malformed response, etc.)Retry after a short delay. Check provider status if persistent
internal_error500Server errorUnhandled exception, database connection failure, or pool exhaustionRetry after a short delay. Check server logs using the requestId

Permanent Errors

Retrying these will not help — the request or configuration must be changed.

CodeHTTP StatusDescriptionCommon CauseFix
auth_error401Authentication failedInvalid API key or revoked tokenCheck your API key or sign in again. See Authentication
session_expired401Session expiredSession token has expired or been revokedSign in again to get a new session
forbidden403Access deniedUser lacks the required role (e.g., admin endpoints require admin role)Request the appropriate role from your Atlas administrator
forbidden_role403Admin role requiredNon-admin user tried to access an admin endpointSign in with an admin account or request the admin role
org_not_found400No active organizationRequest requires an active organization but none is selectedSelect an organization in the org switcher and try again
configuration_error400Atlas is not fully configuredMissing environment variables, invalid config file, or startup diagnostics failedRun atlas doctor to identify the issue. See Troubleshooting
no_datasource400No datasource configuredATLAS_DATASOURCE_URL is not setSet ATLAS_DATASOURCE_URL in your environment. See Environment Variables
invalid_request400Invalid requestMalformed JSON body or missing required fieldsCheck the request body format. See API Reference
validation_error422Request validation failedRequest body doesn't match the expected schema (wrong types, missing fields)Check the details field for specific field errors
not_found404Resource not foundConversation, entity, or other resource doesn't exist or isn't owned by the callerVerify the resource ID. The resource may have been deleted
plan_limit_exceeded429Plan limit exceededWorkspace has exceeded its plan's query or token limit (including the 10% grace buffer)Upgrade your plan or wait until the next billing period
provider_model_not_found400AI model not foundThe model specified in ATLAS_MODEL doesn't exist at the configured providerCheck ATLAS_MODEL and ATLAS_PROVIDER values. See Environment Variables
provider_auth_error503AI provider authentication failedInvalid or expired LLM provider API key (e.g., ANTHROPIC_API_KEY)Verify your provider API key. Regenerate it if expired

Billing & Workspace Errors

These codes are returned by billing enforcement and workspace status middleware. They block requests before the agent loop runs.

CodeHTTP StatusDescriptionCommon CauseFix
trial_expired403Trial has expired14-day SaaS trial endedUpgrade to a paid plan
billing_check_failed503Billing check failedFailed to fetch plan data from internal DBRetry — transient infrastructure issue
workspace_check_failed503Workspace check failedFailed to verify workspace statusRetry — transient infrastructure issue
workspace_throttled429Workspace throttledWorkspace triggered abuse detection thresholdsWait for the throttle delay to pass and retry. See Abuse Prevention
workspace_suspended403Workspace suspendedAdmin suspended the workspaceContact your workspace administrator
workspace_deleted404Workspace deletedWorkspace has been permanently deletedCreate a new workspace

Client Error Codes (ClientErrorCode)

These codes are detected client-side by the SDK and chat UI before parsing a server response. They represent network-level failures or HTTP status patterns.

CodeDescriptionCommon CauseFixRetryable
api_unreachableCannot connect to the Atlas APINetwork failure, DNS resolution error, server not running, or CORS issueCheck the API URL configuration and ensure the server is runningYes
auth_failureHTTP 401 detected before JSON parsingAPI key not sent, expired session token, or wrong auth header formatCheck your API key or sign in againNo
rate_limited_httpHTTP 429 detected before JSON parsingRate limit hit — the response wasn't valid JSON (e.g., from a reverse proxy)Wait 30 seconds and retryYes
server_errorHTTP 5xx detected before JSON parsingServer crashed or upstream proxy error (502, 503)Retry after a short delayYes
offlineBrowser reports no network connectionDevice is offline (detected via navigator.onLine === false)Reconnect to the network — the client may auto-retry when connectivity is restoredYes

Client error codes appear in the clientCode field of ChatErrorInfo, while server error codes appear in the code field. When the server returns valid JSON with a known error code, the server code takes precedence.


SDK Error Codes

The @useatlas/sdk includes additional codes in the AtlasErrorCode type beyond ChatErrorCode. Three are client-side codes detected by the SDK itself (never returned by the server). One (not_available) is returned by server admin and conversation endpoints.

CodeDescriptionOriginRetryable
network_errorfetch() threw an error (connection refused, DNS failure, stream interrupted)SDK client-sideYes
invalid_responseServer returned a 2xx status but the body wasn't valid JSONSDK client-sideNo
unknown_errorServer returned an error response with an unrecognized error codeSDK client-sideNo
not_availableFeature not available (e.g., conversation history without DATABASE_URL)Server (admin/CRUD routes)No

Error Response Format

All Atlas API error responses follow a consistent JSON structure:

{
  "error": "rate_limited",
  "message": "Too many requests. Please wait before trying again.",
  "retryAfterSeconds": 12,
  "retryable": true,
  "requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
FieldTypeDescription
errorstringThe error code (one of the codes listed above)
messagestringHuman-readable description of the error
retryablebooleanWhether retrying the same request may succeed
retryAfterSecondsnumber?Seconds to wait before retrying (only for rate_limited; client-side parsing clamps to 0–300)
requestIdstring?Server-assigned UUID for log correlation. Quote this when reporting issues
detailsobject?Additional context (e.g., Zod validation issues for validation_error)
diagnosticsobject[]?Startup diagnostic results (only for configuration_error)

How Server Codes Map to SDK Errors

When you use the @useatlas/sdk, server error responses are automatically parsed into AtlasError instances:

Server JSON Response          →  SDK AtlasError
─────────────────────          ──────────────────
{ error: "rate_limited" }     →  error.code = "rate_limited"
{ message: "Too many..." }    →  error.message = "Too many..."
HTTP 429                       →  error.status = 429
{ retryable: true }           →  error.retryable = true
{ retryAfterSeconds: 12 }    →  error.retryAfterSeconds = 12

If the server response isn't valid JSON, or the error field isn't a known code, the SDK classifies the error as network_error, invalid_response, or unknown_error depending on the failure mode.


Error Handling with Retry Logic

Use the retryable flag on AtlasError to build generic retry logic without hard-coding error codes:

import { AtlasError, createAtlasClient, type QueryResponse } from "@useatlas/sdk";

const atlas = createAtlasClient({
  baseUrl: "https://api.example.com",
  apiKey: "your-api-key",
});

function sleep(ms: number): Promise<void> {
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function queryWithRetry(
  question: string,
  maxRetries = 3,
): Promise<QueryResponse> {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    try {
      return await atlas.query(question);
    } catch (error) {
      if (!(error instanceof AtlasError)) throw error;

      // Permanent error — retrying won't help
      if (!error.retryable) throw error;

      // Last attempt — no more retries
      if (attempt === maxRetries) throw error;

      // Rate limited — use the server-provided delay
      if (error.code === "rate_limited" && error.retryAfterSeconds) {
        console.log(`Rate limited — waiting ${error.retryAfterSeconds}s`);
        await sleep(error.retryAfterSeconds * 1000);
        continue;
      }

      // Other transient errors — exponential backoff
      const delay = Math.min(1000 * 2 ** attempt, 30_000);
      console.log(`${error.code} — retrying in ${delay}ms (attempt ${attempt + 1}/${maxRetries})`);
      await sleep(delay);
    }
  }

  // Unreachable, but satisfies TypeScript
  throw new Error("Retry loop exited unexpectedly");
}

Handling Specific Codes

Refine behavior for specific error codes after checking retryable:

try {
  await atlas.query("Revenue by region");
} catch (error) {
  if (!(error instanceof AtlasError)) throw error;

  switch (error.code) {
    case "auth_error":
    case "session_expired":
      // Redirect to login or prompt for a new API key
      redirectToLogin();
      break;
    case "forbidden_role":
      // User doesn't have admin access
      showPermissionDenied(error.message);
      break;
    case "configuration_error":
    case "no_datasource":
      // Show setup instructions — the server isn't ready
      showSetupGuide(error.message);
      break;
    case "provider_model_not_found":
    case "provider_auth_error":
      // Admin needs to fix server config
      showAdminAlert(error.message);
      break;
    default:
      if (error.retryable) {
        // Generic transient error — show retry UI
        showRetryButton(error.message);
      } else {
        // Permanent error — show the message to the user
        showError(error.message);
      }
  }
}

See Also

On this page