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

# Errors

> Voyage and inference exception taxonomy

Voyage and inference exceptions derive from `sail.SailError`, the base for
every SDK error. `flush()` raises these on delivery failure; `complete()` and
`fail()` warn instead of raising (the terminal event stays buffered for
retry); `event()` never raises network errors.

```text theme={null}
SailError
├─ VoyageError
│  └─ VoyageHTTPError
│     └─ VoyageNotFoundError
├─ InferenceError
│  └─ InferenceHTTPError
```

```python theme={null}
import sail

try:
    sail.voyage.complete(message="done")
    sail.voyage.flush()  # raise-on-failure delivery confirmation
except sail.VoyageNotFoundError:
    ...  # the Voyage no longer exists for this API key
except sail.VoyageError as exc:
    ...  # any other Voyage delivery failure
```

All SDK network calls are bounded: inference requests default to a 600s
timeout, voyage lifecycle calls to 10s, and `flush()` bounds each batch
send (60s) even when called without a timeout. A wedged connection
surfaces as one of the errors below rather than blocking forever.

## Recommended lifecycle

Most agents should use `with sail.voyage.run(...):`. It emits
`voyage.completed` on a clean exit, emits `voyage.failed` and re-raises on an
exception, and performs the same bounded best-effort terminal delivery as the
manual helpers.

Use `create()` / `complete()` / `fail()` only when your controller's start and
terminal sites are separated, or when you need strict raise-on-failure
confirmation of the terminal lifecycle event. Call `flush()` after the terminal
helper so `voyage.completed` or `voyage.failed` is already in the delivery
buffer:

```python theme={null}
voyage = sail.voyage.create(name="nightly-research", version=1)

try:
    do_work()
except BaseException as exc:
    voyage.fail(error_type="harness_error", message=str(exc))
    voyage.flush()
    raise
else:
    voyage.complete(message="done")
    voyage.flush()
```

## VoyageError

Base class for Voyage SDK delivery errors, such as a flush that times out or
cannot deliver a required terminal event. Subclass of `SailError`.

## VoyageHTTPError

Raised when the Voyage API returns an HTTP error. Subclass of `VoyageError`.

| Attribute     | Type           | Description                 |
| ------------- | -------------- | --------------------------- |
| `status_code` | `int`          | HTTP status code.           |
| `response`    | `dict \| None` | Parsed error response body. |

## VoyageNotFoundError

Raised when a Voyage cannot be found for the current API key (HTTP 404).
Subclass of `VoyageHTTPError`, so it carries `status_code` and `response`.

## InferenceError

Base class for [inference](/voyages-sdk-inference) wrapper errors. Raised, for
example, when an unsupported wrapper option such as `stream=True` is passed, or
when no API key is configured. Subclass of `SailError`.

## InferenceHTTPError

Raised when a Sail inference endpoint returns a non-2xx response. Subclass of
`InferenceError`.

| Attribute     | Type           | Description                 |
| ------------- | -------------- | --------------------------- |
| `status_code` | `int`          | HTTP status code.           |
| `response`    | `dict \| None` | Parsed error response body. |
