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

# Error handling

> Error classes thrown by the ReyGrid TypeScript SDK and how to handle them.

All SDK errors extend `ReyGridError`, so `instanceof` checks work.

```text theme={"system"}
ReyGridError
├── ReyGridApiError            // any 4xx / 5xx
│   ├── ReyGridAuthError       // 401
│   ├── ReyGridValidationError // 400
│   ├── ReyGridNotFoundError   // 404
│   ├── ReyGridConflictError   // 409
│   ├── ReyGridPermissionError // 403 (plan limit, model not on plan, restricted key)
│   └── ReyGridRateLimitError  // 429 (rate limited, key quota used up)
├── ReyGridNetworkError        // fetch failure or timeout
└── ReyGridStreamError         // failure while reading an SSE stream
```

Other statuses (for example 500) throw the base `ReyGridApiError`.

## Properties

| Class | Property | Description |
| - | - | - |
| `ReyGridError` | `message`, `cause?` | Description and underlying error |
| `ReyGridApiError` | `statusCode` | HTTP status |
| | `code` | Error code |
| | `details?` | The API's `error` object: `code`, `message` and, for `INVALID_BODY`, `list` |

## Handling

```typescript theme={"system"}
import {
  ReyGridApiError,
  ReyGridAuthError,
  ReyGridNetworkError,
  ReyGridNotFoundError,
} from "reygrid";

try {
  await client.listMessages("{AgentId}", "user-42");
} catch (err) {
  if (err instanceof ReyGridAuthError) {
    console.error("Invalid API key");
  } else if (err instanceof ReyGridNotFoundError) {
    console.error("No such conversation");
  } else if (err instanceof ReyGridNetworkError) {
    console.error("Network problem:", err.message);
  } else if (err instanceof ReyGridApiError) {
    console.error(`API ${err.statusCode}: ${err.code} — ${err.message}`);
  } else {
    throw err;
  }
}
```

Check subclasses before `ReyGridApiError`.

## Reading error details

`code` and `message` come from the API's `error` object, so you can branch on the [error code](/rest-api/errors#error-codes) directly:

```typescript theme={"system"}
import { ReyGridApiError, ReyGridPermissionError } from "reygrid";

try {
  await client.addTextSource("{AgentId}", { title: "Refunds", content: "…" });
} catch (err) {
  if (err instanceof ReyGridPermissionError && err.code === "PLAN_LIMIT_REACHED") {
    console.error("Upgrade to add more knowledge");
  } else if (err instanceof ReyGridApiError && err.code === "INVALID_BODY") {
    console.error(err.details?.list); // validation errors per field
  } else {
    throw err;
  }
}
```

<Info>
  Before 1.0.3, `code` and `message` were only read from the top level of the body, so most errors surfaced as `HTTP 400` with no code. Upgrade to get the real values.
</Info>

## Retries

The SDK doesn't retry. Retry `ReyGridNetworkError` and 5xx `ReyGridApiError` in your own code, with backoff. Don't retry 4xx errors without fixing the request.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.