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

# Error handling

> All SDK errors are Data.TaggedError — matchable with Effect.catchTag.

## Error types

| Error | When |
| - | - |
| `TokenParseError` | Token is malformed or signature is invalid |
| `TokenExpiredError` | Token `expires_at` is in the past |
| `HttpError` | Server returned a non-2xx status |
| `NetworkError` | Fetch failed (DNS, timeout, no connection) |
| `CodecError` | msgpack decode or schema validation failed |
| `TransportError` | WebSocket error |

## Server-side validation errors

Some ops are rejected by the server with `400` before being applied. These surface as `HttpError` (REST) or `ServerMsg::Error { code: 400 }` (WebSocket):

| Rejection | Affected CRDTs | Detail |
| - | - | - |
| Clock drift > 30s | LwwRegister, Presence | Client HLC timestamp is more than 30 seconds ahead or behind server time. Sync your system clock. |
| Element depth > 1 | ORSet | Element contains nested objects/arrays. Flatten your data structure. |
| WAL write failure | All | Storage is full or unavailable. Server returns `503`. |

## Handling errors

All errors are `Data.TaggedError` from Effect, matchable with `Effect.catchTag`:

```ts theme={null}
import { Effect } from "effect";
import { MeridianClient } from "meridian-sdk";

await Effect.runPromise(
  MeridianClient.create(config).pipe(
    Effect.catchTag("TokenExpiredError", (e) =>
      Effect.die(`Token expired at ${new Date(e.expiredAt).toISOString()}`)
    ),
    Effect.catchTag("TokenParseError", () =>
      Effect.die("Invalid token — check MERIDIAN_TOKEN")
    ),
    Effect.flatMap((client) =>
      client.http.getCrdt("my-room", "gc:views").pipe(
        Effect.catchTag("HttpError", (e) =>
          Effect.succeed(`Server error ${e.status}: ${e.body.message}`)
        ),
        Effect.catchTag("NetworkError", (e) =>
          Effect.succeed(`Network error: ${e.message}`)
        ),
      )
    ),
  )
);
```

## Error fields

```ts theme={null}
TokenParseError   → { message: string }
TokenExpiredError → { expiredAt: number }  // ms timestamp
HttpError         → { status: number; body: { message: string } }
NetworkError      → { message: string; cause?: unknown }
CodecError        → { message: string; raw: Uint8Array }
TransportError    → { message: string; cause?: unknown }
```


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