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

# Errors

> Everything SORY raises, and when.

Every error derives from `SoryError`, so one `except` covers the library:

```python theme={"dark"}
from sory import SoryError

try:
    order = await sory.place(side="buy", qty=Decimal("2"), order_type="market")
except SoryError as e:
    ...
```

| Error             | Raised when                                                                                                                      |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `LicenceError`    | The key is missing, malformed, unsigned or expired. Checked when the client is built.                                            |
| `ConfigError`     | The config is invalid, or an order breaks a rule — a limit with no price, a market with one, a limit naming more than one venue. |
| `FeeError`        | A `fee_offset` names a venue with no rate. Subclass of `ConfigError`.                                                            |
| `VenueError`      | A venue id is unknown, unregistered, or cannot be reached.                                                                       |
| `CapabilityError` | The order needs something the venue has not proven it can do — `post_only`, `margin`, an `IOC`.                                  |
| `RoutingError`    | There is no book, or nothing could be allocated.                                                                                 |
| `ExecutionError`  | An order could not be sent, cancelled or tracked.                                                                                |

## The ones you will actually hit

**Building the client** raises `LicenceError` or `FeeError` immediately — both mean a mistake in the config, and both are better found now than mid-session.

```text theme={"dark"}
FeeError: Fee schedule is incomplete, missing: okx BTC/USDT
```

**Sending an order** raises `ConfigError` for a shape that cannot work, and `CapabilityError` when a venue cannot do what you asked:

```text theme={"dark"}
ConfigError: A limit order rests on one venue; got 3
CapabilityError: bybit does not declare time_in_force=IOC; it declares GTC
```

A `CapabilityError` is always a refusal, never a downgrade. SORY will not send your order without the thing you asked for.

## What is not an error

A partial fill is not an error, and neither is a venue dropping out. Those come back as data:

```python theme={"dark"}
plan.unallocated          # what could not be placed
plan.unallocated_reason   # why, in words
book.excluded             # {venue: why it is not contributing}
order.unfilled_reason     # why `remaining` is not zero
```

<Note>
  A slice too small for one venue is re-routed to another rather than raised. You only get a `RoutingError` when *nothing* could be allocated anywhere — and its message names every venue that was considered and why each was skipped.
</Note>

## Logging

Every error is logged before it is raised, with the function that produced it. Point the log wherever you want:

```python theme={"dark"}
config = {"symbol": "BTC/USDT", "log_dir": "./logs"}
```
