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

# Error handling

> How Everabyte reports failures, why there are three envelope shapes, and how to decode them safely.

Everabyte does not use a single error envelope. The shape depends on where the failure occurred. A robust client handles all three.

## Three shapes

### 1. Controller success

```json theme={null}
{
  "status": 200,
  "message": "Files retrieved",
  "data": []
}
```

### 2. Controller error

```json theme={null}
{
  "status": 400,
  "message": "name: String must contain at least 1 character(s)",
  "error": null
}
```

### 3. Guard or middleware error

```json theme={null}
{
  "status": 403,
  "message": "This API key is restricted to specific buckets.",
  "data": null,
  "code": "API_BUCKET_SCOPE_DENIED"
}
```

The third shape carries a stable `code`. The second generally does not. Some framework-level errors use `{ statusCode, error, message }` instead.

## What to branch on

Use this order:

1. **HTTP status** — always present and authoritative.
2. **`code`** — stable when present; safe to branch on.
3. **`data.status`** — required for endpoints that wrap a service result (version list, version restore, version delete, and file restore).
4. **`message`** — for humans only. It is localized and may change.

Never write `if (message === "...")`.

## Decoding example

```typescript theme={null}
type ApiFailure = {
  status?: number;
  statusCode?: number;
  message?: string;
  code?: string;
  error?: unknown;
  data?: { status?: number; message?: string } | null;
};

async function parseFailure(response: Response): Promise<ApiFailure> {
  const contentType = response.headers.get("content-type") ?? "";
  if (!contentType.includes("application/json")) {
    return { status: response.status, message: await response.text() };
  }
  return (await response.json()) as ApiFailure;
}
```

## The 5xx rule

In production, 5xx messages are sanitized. The client receives a generic message instead of a database or driver error. The original detail is logged server-side and sent to error tracking.

Do not expect to diagnose a 500 from the response body. Correlate with the timestamp, route, and your request ID.

## Partial success

Some operations can partially succeed:

* A multi-file upload returns only the first file's result.
* A folder copy copies a subtree and reports counts.
* A batch-style operation may report per-item results.

Treat counts as data, not as proof that every intended item succeeded. Re-read the affected collection when correctness matters.

## Nested failures

File restore and version list, restore, and delete endpoints return HTTP `200` with an inner service status:

```json theme={null}
{
  "status": 200,
  "message": "File restored from trash",
  "data": {
    "status": 404,
    "message": "File not found",
    "data": null
  }
}
```

A client that only checks `response.ok` will treat this as success. Check `data.status` for these endpoints.

## Retry matrix

| Status | Retry | Notes |
| - | - | - |
| `400` | No | Fix the request |
| `401` | No | Fix credentials |
| `402` | No | Billing or storage capacity |
| `403` | No | Permission, scope, surface, or policy |
| `404` | No | Wrong identifier or no access |
| `410` | No | Restore window elapsed |
| `413` | No | File too large for the plan or trial |
| `429` | Yes | Backoff with jitter |
| `500` | Maybe | Retry reads; verify writes first |
| `502`, `503`, `504` | Yes | Backoff; contact support if it persists |

## Error handling checklist

> [!TIP]
>
> Check HTTP status before parsing `data`.

> [!TIP]
>
> Branch on `code` when present.

> [!TIP]
>
> Handle nested `data.status` for version and restore endpoints.

> [!TIP]
>
> Never display raw 5xx bodies to users.

> [!TIP]
>
> Log route templates, status, and stable codes — never secrets.


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