> AI agents: this is one page from Mammoth Analytics documentation. The index of all pages as Markdown is https://docs.mammoth.io/llms.txt. Append `.md` to any docs URL, or send `Accept: text/markdown`, to get Markdown.

# Mammoth errors and exit codes

> The CLI error envelope, the exit-code table, which failures are worth retrying, and the per-method rate limits that apply to every caller.

How failures are reported, which of them are worth retrying, and which are a bug in the request.

## Read the envelope, not the text

In machine output the CLI writes a versioned envelope. Success goes to stdout; errors go to stderr. Branch on the exit code and the stable `error.code`, never on the human-readable message.

**Success, stdout:**

```json
{"schema_version": 1, "data": "<result>", "meta": {"command": "…", "profile": "default", "workspace_id": 4, "project_id": 180}}
```

`meta` carries only the keys that have a value. It adds `pagination` on a paged read, and `update_available` (`{"current", "latest", "command"}`) when a newer CLI release exists. The CLI checks once a day, after a command, and never blocks on it. It installs a newer release by itself only in an interactive terminal; in CI, in a pipe or in an agent run it only reports `update_available`. `MAMMOTH_AUTO_UPGRADE=1` forces the install on, and `MAMMOTH_NO_UPDATE_CHECK=1` turns the check off.

### A write returns what it did

Every command that changes something adds two blocks to `data`. Read them before you build on the change.

- `verify` is the CLI's own verdict: `verified` (true or false), a `state`, any `warnings`, a `reason` when it is not verified, and `needs_user`. When `needs_user` is set, stop and tell a person before the next step. A row-changing step also carries `rows_before` and `rows_after`.
- `outcome` is `settled`, `pending`, `partial` or `failed`. The envelope's top-level `status` follows the last three: `partial` exits 3, and `failed` exits 1 even though the API call itself went through (`verify.reported_status` keeps the earlier word).
- A write still running when the wait ends reports `status: pending` and `verify.next_command` (`mammoth view pipeline wait VIEW_ID`, or `mammoth job wait ID` for an automation). It exits 0: the change was accepted, so wait on it and never replay it.
- `state` is a fresh read of what the write produced, taken after it settled, not echoed from your request. If that read fails, `state` says `unreadable` and `verify.verified` becomes false.

A success envelope proves the call went through. The `state` block shows the outcome.

**Error, stderr:**

```json
{"schema_version": 1, "error": {"code": "…", "message": "…", "summary": "…", "hint": "…", "details": {}, "request_id": null, "retryable": false, "authorization_required": false, "recovery_commands": ["…"], "log_ref": {"file": "…", "run_id": "…"}}}
```

`summary` is a plain-language sentence you can show a person. `log_ref` points at the local run log: `mammoth log tail --input '{"run_id": "RUN_ID"}'` lists every request that run made, with its HTTP status and the backend `request_id`. Quote both when you report a backend fault.

`schema_version` is a compatibility contract. It is `1` today and increments only on a breaking change to the envelope shape. Check it if you parse envelopes across CLI upgrades.

## Exit codes

| Code | Meaning | Retry? |
| --- | --- | --- |
| 0 | Success | n/a |
| 1 | API error | no |
| 2 | Usage, input, or confirmation failure | no |
| 3 | Partial: a write whose read-back shows only part of it took effect | no |
| 4 | Authentication failure | no |
| 5 | Not found | no |
| 6 | Conflict, including `file_exists` when an export would overwrite a local file | no |
| **7** | **Retryable (network or timeout)** | **yes** |
| 130 | Interrupted | no |

> **Never retry a mutation on anything but 7**
>
> The CLI does not retry a mutation without a real server idempotency contract, and neither should your code. An interruption returns `130` and closes sessions and files cleanly.

A timeout, exit code `7` or an interruption does not prove a write failed. When `details.operation_state` is `outcome_unknown`, the change may have committed: reconcile it with `mammoth job get` or a read of the resource before you replay it.

Exit 3 is not a transport failure. Read `verify` to see which part of the write took effect, finish or undo it, and do not replay the whole command.

## Commands the server does not offer yet

The data-app commands and `schedule create` fail at once with the error code `feature_unavailable` and send no request. They do not appear in `mammoth schema find`.

## Local checks

`view transform extract-date`, `date-diff`, `increment-date` and `math` check column types before any request. A TEXT column is refused with `column_type_mismatch`, and the error names the `convert-type` command to run first. An unexpected fault in the CLI itself is reported as `internal_error`; rerun with `--debug` for the stack trace.

A command that writes a local file (`view export csv`, `dashboard bi-export`, `explore-panel export-image`, `support template export`) refuses an existing file with `file_exists` (exit 6) unless you pass `--overwrite`.

## Confirmation failures

A mutation that needs a confirmation and does not get one fails with exit code `2` and an error code of `confirmation_required` or `confirmation_target_mismatch`. It never proceeds and never prompts off a terminal. The rule is the same everywhere: an action that cannot be undone needs `--yes`, and a `confirm_target` command also needs `--confirm ID` with the exact target id. The CLI checks `--confirm` before it makes any API call.

## On the HTTP side

Calling the API directly, a bad or missing credential returns **401**; an authenticated caller without permission gets **403**. The Python SDK raises `MammothAuthError` for the first.

Measured across all 471 operations in the v2 spec, the responses you will in fact meet are `400` (declared on 463), `403` (275), `404` (50), `202` (82, an async job), `422` (6) and `409` on exactly two. Those two are worth special handling: a `409` means you tried to delete a parameter or snippet that is still referenced, and it is the case a user most needs a clear message for.

> **There is no uniform response envelope on the REST API**
>
> Successful responses return the resource schema directly. Error responses carry `{status_code, detail, extra}`. The `{data, meta}` envelope belongs to the CLI, not to the API, so do not write a client that expects a `data` wrapper from HTTP.

## Rate limits

Limits are **per HTTP method** and they apply to **every caller**, not only to paid tiers.

| Method | Requests per minute |
| --- | --- |
| `GET` | 600 |
| `POST` | 300 |
| `PATCH` | 60 |
| `DELETE` | 60 |

A fixed one-minute window, counted in Redis, keyed on your session when authenticated and on the caller IP when not. That last detail matters if you are embedding: anonymous dashboard viewers share a limit by IP.

> **429 is declared on none of the 471 operations**
>
> The OpenAPI spec does not advertise a 429 response anywhere, so a client generated from the spec will not have a handler for one. Write the retry yourself, and back off rather than hammering the window.

> **There is no daily quota**
>
> Not for any tier. The one-minute window above is the only limit that exists. If you have designed against a daily request allowance, it was never real.

## The business error object

Some endpoints carry a richer error *inside* the transport envelope. It is real in the implementation but not discoverable from the spec, so expect the Litestar envelope at the transport level and look for the business error within it. Do not write a client that expects the business object as the top-level body.

> **One letter apart, two different contracts**
>
> The API business error uses `error_code`. The CLI envelope uses `error.code`. A client that reads the wrong one silently finds nothing.

## Next up

- [Agents and CI](https://docs.mammoth.io/agents/ci)—the reliable operation loop, end to end.
- [Blast radius and safety](https://docs.mammoth.io/agents/safety)—what each command will demand before it runs.

---
Source: https://docs.mammoth.io/build/errors.md · Updated: 2026-10-15