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

# Errors

> One error shape, the codes it carries, and which failures are worth retrying.

# Errors

Every Workflows failure returns the same envelope. You can write one handler.

```json theme={null}
{
  "error": "invalid_graph",
  "message": "The composition graph is not valid. See details.errors.",
  "details": {
    "errors": [
      { "code": "unmet_requirement", "nodeId": "pack", "requires": ["research_document"] }
    ]
  }
}
```

| Field     | Guarantee                                                                                                                  |
| --------- | -------------------------------------------------------------------------------------------------------------------------- |
| `error`   | A stable machine-readable code. Branch on this. It is never localised and never reworded.                                  |
| `message` | One sentence a developer can act on. Always present. Do **not** branch on it, because the wording can change.              |
| `details` | Case-specific structure: validation faults, the offending id, the limit you exceeded. Absent when there is nothing to add. |

<Note>
  Responses currently repeat some `details` entries at the top level as well.
  For example `destinationId` appears both in `details` and beside `error`. Those
  duplicates are a migration aid for clients written before the envelope existed
  and will be removed. Read from `details`.
</Note>

## Authentication is the one exception

Credential failures are answered by the platform gateway, before the request
reaches Workflows, and use the platform-wide shape:

```json theme={null}
{ "error": { "code": "UNAUTHENTICATED", "message": "Not authenticated" } }
```

So `error` is an **object** on a 401 and a **string** on everything else. Check
the status code first and you will never have to tell them apart.

## Authentication and access

| Status | Code                    | Retry? | Meaning                                                          |
| ------ | ----------------------- | ------ | ---------------------------------------------------------------- |
| 401    | `UNAUTHENTICATED`       | No     | Missing credential, or a key that is unknown, revoked or expired |
| 402    | `plan_required`         | No     | Plan does not include Workflows                                  |
| 403    | `insufficient_scope`    | No     | Key lacks `read:workflows` or `write:workflows` for this route   |
| 403    | `GATE_REQUIRED`         | No     | An acceptance is outstanding on the account                      |
| 429    | `rate_limited`          | Yes    | API rate limit exceeded. Wait for the reset time                 |
| 502    | `UPSTREAM_ERROR`        | Yes    | The authorization service was unreachable                        |
| 503    | `workflows_unavailable` | No     | Not available in your region                                     |

## Authoring

| Status | Code                                           | Meaning                                                                              |
| ------ | ---------------------------------------------- | ------------------------------------------------------------------------------------ |
| 400    | `invalid_graph`                                | The graph broke one or more rules; see `details.errors`                              |
| 400    | `invalid_graph_nodes`                          | Trigger, gate or destination nodes were malformed                                    |
| 400    | `invalid_dag`                                  | The saved definition failed validation at publish                                    |
| 400    | `name_required`                                | Workflow name missing                                                                |
| 400    | `name_too_long`                                | Over `details.max` characters (200)                                                  |
| 400    | `scope_required`                               | A version must carry a pin (`scope.terminal`) or a graph (`scope.graph`)             |
| 400    | `draft_not_runnable`                           | The draft has no research steps yet                                                  |
| 400    | `unattended_not_safe`                          | A scheduled or event trigger needs every step marked safe to run unattended          |
| 403    | `destination_manage_required`                  | Managing an organisation destination requires the manager role                       |
| 404    | `not_found`                                    | No such workflow, version or run, or not visible to you                              |
| 404    | `destination_not_found` / `universe_not_found` | See `details` for which id                                                           |
| 409    | `workflow_quota_exceeded`                      | Workflow limit reached; archive one to create another                                |
| 422    | `destination_cannot_carry_research`            | The destination has no mapping for research output and would silently skip every run |

Graph fault codes inside `details.errors` are listed in
[Definitions](/api-reference/workflows/definitions#validation-faults).

## Running

| Status | Code                            | Retry? | Meaning                                               |
| ------ | ------------------------------- | ------ | ----------------------------------------------------- |
| 400    | `question_too_long`             | No     | Over `details.max` characters (1000)                  |
| 400    | `not_scheduled`                 | No     | The published version does not run on a schedule      |
| 402    | `research_capacity_unavailable` | No     | Usage allowance exhausted for the period              |
| 404    | `no_published_version`          | No     | Nothing published to run                              |
| 409    | `idempotency_conflict`          | No     | That `Idempotency-Key` was used with a different body |
| 422    | `no_execution_host`             | No     | No host can run this composition                      |
| 500    | `dispatch_failed`               | Yes    | The run could not be handed to its host               |
| 503    | `research_capacity_unavailable` | Yes    | The usage system was unavailable                      |

Retry `502`, `503` and `429` with backoff. Never retry a run without the
original `Idempotency-Key`. See [Runs](/api-reference/workflows/runs#idempotency).

## Unknown codes

New codes are added over time. Treat a code you do not recognise as a failure
of its status class (4xx is your bug, 5xx is ours) and show `message` to
whoever is watching. An unrecognised code is never a success.

## Subject resolution

`resolve-subjects` returns `200` with an `unresolved` array rather than an
error, because a partial result is useful: some companies pin while others
need a choice.

| Reason          | Meaning                                              | What to do                                          |
| --------------- | ---------------------------------------------------- | --------------------------------------------------- |
| `ambiguous`     | Several companies match, or none could be identified | Re-resolve with a candidate's ticker, or with a RIC |
| `unlisted`      | Held by Briefed, but with no listed equity           | Nothing to run against; pick a listed entity        |
| `lookup_failed` | The resolver could not be reached                    | Retry. This asserts nothing about the company       |

When candidates are offered they are the fabric's own matches, and tickerless
candidates are never offered because pinning one gives a run nothing to work
with.

## Reporting a problem

Every response carries `X-Request-ID`. Include it when reporting an issue.
