---
title: How to read errors
description: The platform's single error sink — the shape of an error event, the filters on GET /api/v1/errors, and the standard flow for investigating a failed run.
locale: en
version: 0.2.0
canonical: https://enterium-developer-docs.pages.dev/developers/guides/reading-errors/
---

> Documentation index: https://enterium-developer-docs.pages.dev/developers/llms.txt — every page of this portal has a Markdown twin at <route>.md; the frozen API contract is at https://enterium-developer-docs.pages.dev/developers/api/openapi.json.

Every captured failure across the platform lands in one durable **error
sink**, readable via one endpoint. If something went wrong, this is where
you look first.

## The endpoint

```sh
curl -fsS "https://entherium.duckdns.org:8443/api/v1/errors?limit=20" \
  -H "Authorization: Bearer <TOKEN>"
```

Filters (all optional, combined with AND):

| Parameter | Meaning |
| --- | --- |
| `source` | Where it happened: `http`, `background-loop`, `batch`, `sse`, `startup` |
| `operation` | The stable operation label, e.g. `POST /api/v1/runs` or `projector` |
| `since` | UTC datetime — only events after this moment |
| `limit` | 1–500, default 100; newest first |

## The shape of one event

```json
{
  "guid": 123,
  "source": "batch",
  "operation": "generate step_07",
  "exc_type": "StepError",
  "error": "…message, truncated at 2000 chars…",
  "context": { "run_guid": 456, "contract": 789 },
  "createtime": "2026-07-23T02:14:05Z"
}
```

`context` is a dictionary of relevant identifiers with secrets stripped;
it may be null. Use it to cross-reference the run and contract.

## Standard flow: "a run failed — what happened?"

1. Note the run's start time (from the run record or the report).
2. Fetch errors since then, scoped to batch work:

   ```sh
   curl -fsS "https://entherium.duckdns.org:8443/api/v1/errors?since=<RUN_START_UTC>&source=batch&limit=50" \
     -H "Authorization: Bearer <TOKEN>"
   ```

3. Read `operation` (which step), `exc_type` and `error` (what broke), and
   `context` (which run/contract).
4. If nothing is there, widen: drop `source` — the failure may have been in
   a background loop (`source=background-loop`) rather than the batch
   itself.
5. Correlate with the run's `run_step` records: the failed step and the
   error event should agree. The run record is ground truth for *where* it
   stopped; the error event for *why*.

## Caveats

- **The sink is best-effort by design.** The write happens asynchronously;
  a crash during process startup (before the event loop runs) may leave
  only a log line and no event row. Absence of an error event is therefore
  weaker evidence than presence of one.
- **Fail-loud philosophy:** platform steps do not swallow errors into
  defaults, so a genuinely failed run will be visible either here or in the
  run's step records — silence plus a completed run means success, not a
  hidden failure.
