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

# Errors

> How the TrueMath API reports transport-level errors via HTTP status codes, and calculation errors within a successful response.

TrueMath distinguishes two kinds of failure: **transport errors** (the request itself was malformed or unauthorized) and **calculation errors** (the request was valid but the calculation could not complete).

## Transport errors

Transport errors use a standard HTTP status code and a JSON body of the form:

```json theme={null}
{ "error": { "code": "error_unauthorized", "message": "..." } }
```

| Status | Code                         | Meaning                                                                                       |
| ------ | ---------------------------- | --------------------------------------------------------------------------------------------- |
| `400`  | `error_invalid_json`         | The request body is not valid JSON.                                                           |
| `401`  | `error_unauthorized`         | Missing, malformed, or invalid API key.                                                       |
| `403`  | `error_disabled_api_key`     | The API key has been revoked or disabled.                                                     |
| `409`  | `error_idempotency_conflict` | An `Idempotency-Key` was reused with a different body. See [Limits](/api/limits#idempotency). |
| `422`  | `error_invalid_param`        | A parameter is missing or out of range.                                                       |
| `5xx`  | `error_server_internal`      | An unexpected server error.                                                                   |

## Calculation errors

A calculation that cannot complete returns an HTTP `200` with `status: "error"` in the body and an `errors` array — one entry per problem. Each entry has:

* **`code`** — a stable, machine-readable identifier for the failure. Branch on this, not on `message`. The full set is listed [below](#calculation-error-codes).
* **`message`** — an English description **template** containing numbered `%argN%` placeholders. It is *not* pre-filled; substitute the `args` before displaying it (see [Building the message](#building-the-message)).
* **`args`** — a positional array of string values for the `%argN%` placeholders in `message` (`%arg0%` → `args[0]`, `%arg1%` → `args[1]`, and so on). Read them directly when you need the raw values, such as the unit names. See [Building the message](#building-the-message).
* **`offset`** — present only on `input.syntax_error`: an integer, the zero-based character offset of the error within the [equation](/authoring/writing-equations). It is a caret position *between* characters — `0` is before the first character, `1` is after the first, `2` after the second, and so on.
* **`missing`** — when the calculation is blocked on inputs, the variables you could supply to continue, grouped as alternatives. See [Missing inputs](#missing-inputs).

`args`, `offset`, and `missing` are each **conditionally included** — present only when the error uses them, and omitted (never `null`) otherwise. A consumer must not assume the keys exist.

An incompatible-units error, for example, carries the offending units in `args`, to substitute into the `message` template:

```json theme={null}
{
  "status": "error",
  "errors": [
    {
      "code": "input.incompatible_units",
      "message": "The unit '%arg0%' and the unit '%arg1%' are not compatible",
      "args": ["m", "in²"]
    }
  ],
  "version": 1
}
```

#### Building the message

`message` is a template, not a finished string. Each placeholder is a numbered token `%argN%` (zero-indexed), filled from `args` **by index** — `%arg0%` is replaced with `args[0]`, `%arg1%` with `args[1]`, and so on (the reference client matches `/%arg(\d+)%/g`):

```yaml theme={null}
template: "The unit '%arg0%' and the unit '%arg1%' are not compatible"
args:     ["m", "in²"]
result:   "The unit 'm' and the unit 'in²' are not compatible"
```

Substitution rules:

* If `args` is absent or empty, render `message` as-is — it has no placeholders to fill.
* Replace each `%argN%` with `args[N]`. The values are already strings in the response.
* Match by index, not order of appearance: `%arg1%` always means `args[1]`, even if it appears before `%arg0%` in the text.
* If a placeholder's index has no matching value (`N` is at or beyond the length of `args`), leave the literal `%argN%` token in place — do not blank it.

If you only need the offending values — to highlight a field, say — read them straight from `args` and ignore `message`. The same substitution applies to every error, engine- or request-originated.

#### Missing inputs

When an error is blocked on inputs, `missing` lists the variables you could supply to continue. It is an **array of option groups** — each inner array is one set of variables that must be supplied **together** to unblock the calculation. More than one group means there are **alternative** ways to proceed. Read `missing` as: provide every variable in any one group, then retry.

Each entry is a fully formed [variable](/concepts/variables) object — `id`, `key`, `title`, `description`, and a `display` render snapshot (the same `display` shape as a [calculation result](/api/calculate#display-formats)) — but with **no `value`**, since these are candidates you can supply, not resolved values.

```json theme={null}
{
  "status": "error",
  "errors": [
    {
      "code": "calculation.unable_to_resolve_target",
      "message": "Not able to resolve this combination of inputs and requested calculation",
      "missing": [
        [
          {
            "id": "...",
            "key": "down_payment",
            "title": "Down payment",
            "description": "...",
            "display": { "data_type": "number", "display_type": "number", "decimal_format": "decimals_2" }
          }
        ]
      ]
    }
  ],
  "version": 1
}
```

The example has one group with one variable, but a group may list **several** variables that must be provided together, and there may be several groups. For instance, one group might ask for both `down_payment` and `loan_term` while another asks only for `loan_amount` — satisfying *either* group (all of its variables) lets the calculation continue.

### Calculation error codes

Codes are namespaced by category — `input.*` for a malformed or under-specified request, `calculation.*` for a valid request the system cannot solve, and `math.*` for an undefined numeric result. Branch on the exact `code`.

**Input errors** — the request is malformed or under-specified:

| Code                             | Meaning                                                                                                                                                                                                                                  |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `input.unknown_domain`           | The requested domain does not exist.                                                                                                                                                                                                     |
| `input.unpublished_domain`       | The domain has not been published; publish it before use.                                                                                                                                                                                |
| `input.unknown_scenario`         | The calculation references a scenario that does not exist.                                                                                                                                                                               |
| `input.missing_calculate_target` | No calculation target was named — the request did not specify a variable to solve for.                                                                                                                                                   |
| `input.unknown_calculate_target` | A target was named, but it is not a variable in this domain.                                                                                                                                                                             |
| `input.invalid_prompt`           | The input could not be parsed.                                                                                                                                                                                                           |
| `input.invalid_format`           | A value provided for a key has an invalid format.                                                                                                                                                                                        |
| `input.invalid_input_schema`     | A `json` request body parsed as JSON but does not match the [input schema](/concepts/input-formats#json). A `prompt` that cannot be parsed as JSON at all returns the transport error [`error_invalid_json`](#transport-errors) instead. |
| `input.invalid_variable_name`    | A variable name is empty or uses illegal characters — names must start with a letter and contain only letters, numbers, and underscores.                                                                                                 |
| `input.invalid_argument`         | A function was called with the wrong number or type of arguments.                                                                                                                                                                        |
| `input.invalid_dimensions`       | A table input is structurally invalid — rows have differing column counts, or a table is nested inside another table.                                                                                                                    |
| `input.invalid_unit`             | A unit in the input is unknown or invalid.                                                                                                                                                                                               |
| `input.incompatible_units`       | An equation or definition combines units that are not dimensionally compatible — for example, adding meters to seconds.                                                                                                                  |
| `input.incompatible_type`        | An operation was attempted between values whose types do not support it — such as adding, dividing, comparing, or negating incompatible types.                                                                                           |
| `input.missing_value`            | A required variable referenced by the calculation has no value supplied.                                                                                                                                                                 |
| `input.syntax_error`             | An equation or variable definition could not be compiled — it contains a syntax error. Carries an `offset` to the location.                                                                                                              |
| `input.timeout_error`            | Natural-language processing took too long; try again.                                                                                                                                                                                    |
| `input.llm_no_parsed_data`       | No recognized inputs or a calculation target were found for the selected domain. The unified "nothing recognized" signal across all input formats.                                                                                       |
| `input.unknown_llm_error`        | An unexpected error occurred while translating natural language.                                                                                                                                                                         |

<Note>
  `input.missing_calculate_target` and `input.unknown_calculate_target` are distinct codes: the first means no target was named in the request; the second means the named target is not a variable in this domain.
</Note>

**Calculation errors** — the inputs are valid but the system cannot solve for the target:

| Code                                   | Meaning                                                                                                                                                                     |
| -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `calculation.circular_reference`       | A variable depends on itself, directly or through a cycle of other variables.                                                                                               |
| `calculation.conflicting_results`      | The requested target resolved to more than one value from the supplied inputs — an inconsistent, over-determined system.                                                    |
| `calculation.undefined_variable`       | An equation references a variable name that is not defined anywhere in the domain.                                                                                          |
| `calculation.unable_to_resolve_target` | The supplied inputs and requested target are not solvable — not enough is known to reach the target. Often accompanied by a `missing` list of inputs that would unblock it. |
| `calculation.unknown_error`            | An unexpected error during execution.                                                                                                                                       |

**Math errors** — a numeric result is undefined or unrepresentable:

| Code                     | Meaning                                                                     |
| ------------------------ | --------------------------------------------------------------------------- |
| `math.divide_by_zero`    | A division by zero occurred during evaluation.                              |
| `math.positive_infinity` | Evaluation produced positive infinity.                                      |
| `math.negative_infinity` | Evaluation produced negative infinity.                                      |
| `math.not_a_number`      | Evaluation produced an undefined numeric result (NaN) — for example, `0/0`. |
| `math.out_of_range`      | A variable's value fell outside its range of valid values.                  |
