> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gatelit.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error codes, HTTP statuses, and error handling patterns for the Gatelit gateway API.

## Error response shape

All gateway errors return JSON with a consistent structure:

```json theme={null}
{
  "code": "unauthorized",
  "message": "Token has expired",
  "requestId": "req_01j9k2m3n4p5q6r7s8t9"
}
```

<ResponseField name="code" type="string">
  Machine-readable error code. Use this to branch your error handling logic.
</ResponseField>

<ResponseField name="message" type="string">
  Human-readable description of what went wrong.
</ResponseField>

<ResponseField name="requestId" type="string">
  The unique gateway request ID. Use this to find the request in the Gatelit dashboard logs.
</ResponseField>

<Tip>
  Successful responses also include the request ID in the `x-gatelit-request-id`
  response header. Save it alongside any response you store so you can look up
  the full logs later.
</Tip>

***

## Error codes

### `unauthorized` — 401

The request could not be authenticated.

**Common causes:**

* The token has expired (signed tokens default to a 60-second TTL).
* The token signature is invalid — check that you are signing with the correct secret.
* The `Authorization` header is missing or malformed.
* A `GatelitKey` has been revoked.

**Resolution:** Ensure your `getToken` implementation fetches a fresh token before each request and that the signing secret matches the one configured in the dashboard.

***

### `gateway_error` — 400

The request was malformed or contained invalid data.

**Common causes:**

* Request body is not valid JSON.
* The `model` field is missing or not in `"provider/model-name"` format.
* A required prompt variable was not supplied when calling `/v1/prompts/:id/run`.
* An invalid value was provided for a typed prompt variable (e.g. passing `"hello"` for a `number` variable).

***

### `gateway_error` — 404

The requested resource does not exist.

**Common causes:**

* The prompt ID in `/v1/prompts/:id/run` does not match any prompt in your organisation.
* The prompt exists but has no published version — only published versions are executed.
* The request path is not a recognised gateway route.

***

### `provider_error` — 4xx / 502

The upstream LLM provider returned an error. The gateway forwards the provider's HTTP status and error message directly.

**Common causes:**

* The provider rate-limited the request (429).
* The requested model is not available or the provider account lacks access.
* The input exceeded the model's context window.
* The provider's API is temporarily unavailable (502).

**Resolution:** Inspect `message` for the provider's original error text. Configure a [fallback chain](/api/chat-completions#body-x-gatelit-fallback-chain) to automatically retry on `rate_limit` or `provider_error` triggers.

***

### `invalid_json` — client-side

Thrown by the JS SDK's `chatJson()` method, not by the gateway itself. Indicates the model returned a response that could not be parsed as JSON, despite an `outputSchema` being set.

**Resolution:** Retry the request. If the problem persists, use a more capable model or tighten the system prompt to reinforce the JSON output requirement.

***

## Handling errors in code

Use the `GatelitError` class from `@gatelit/sdk` to distinguish gateway errors from other exceptions. It exposes `code`, `message`, and `status`.

```ts theme={null}
import { GatelitClient, GatelitError } from "@gatelit/sdk"

const client = new GatelitClient({
  gatewayUrl: "https://gateway.yourapp.com",
  getToken: async () => {
    const res = await fetch("/api/ai-token").then((r) => r.json())
    return { token: res.token, scheme: "GatelitSigned" }
  },
})

try {
  const response = await client.chat({
    model: "openai/gpt-4o",
    messages: [{ role: "user", content: "Hello" }],
  })
  console.log(response.content)
} catch (err) {
  if (err instanceof GatelitError) {
    switch (err.code) {
      case "unauthorized":
        // Token expired or invalid — redirect to sign-in or refresh token
        console.error("Auth error:", err.message)
        break
      case "provider_error":
        // Upstream provider failed — surface to user or retry
        console.error(`Provider error (${err.status}):`, err.message)
        break
      case "gateway_error":
        // Bad request or not found
        console.error("Gateway error:", err.message)
        break
      default:
        console.error(`Unexpected error [${err.code}]:`, err.message)
    }
  } else {
    // Non-Gatelit error (network failure, etc.)
    throw err
  }
}
```

### In the Vue SDK

When using `useGatelit`, errors are captured in the `error` ref rather than thrown. Check it reactively:

```vue theme={null}
<template>
  <div v-if="error" class="error-banner">
    <template v-if="error.code === 'unauthorized'">
      Your session has expired. Please sign in again.
    </template>
    <template v-else>
      Something went wrong: {{ error.message }}
    </template>
  </div>
</template>
```

The `error` ref is reset to `null` at the start of the next `send()` call, and also when you call `clear()`.

***

## Locating requests in the dashboard

Every request — successful or failed — is assigned a `requestId`. You can find it in:

* The `x-gatelit-request-id` **response header** on successful requests.
* The `requestId` field in the **error response body** on failed requests.
* The `meta.requestId` property on `ChatResponse` objects returned by the JS SDK.

Use this ID in the **Logs** section of the Gatelit dashboard to view the full request details, token usage, latency, model used, and any upstream provider errors.
