Skip to content

Error codes

The enum lives in packages/schema/src/errors.ts (ERROR_CODES, a readonly tuple; AxiomError carries code, message, optional path and details). Adding a code means adding it there first; the check-error-codes guard fails CI on any "ERR_*" literal elsewhere that is not in the list, and on any code that no behavioural test asserts. Removing a code or changing which code a failure produces is a major (versioning.md).

How a code reaches a caller:

Surface Shape
MCP tool isError: true result whose text is { code, message, path?, details? } — a handler never throws; apply/check failures that are results (ApplyResult.error, Finding.facts.code) come back as normal results with the code inside
CLI result objects (ApplyResult, CheckReport) on stdout with exit 1; everything else { error: { code, message, details? } } with exit 2
Library (@codai/axiom-*) AxiomError thrown, except apply() which always returns an ApplyResult with error.code
Gate AXIOM GATE DENY <code>: <reason> on stderr, axiom.code in the stdout JSON

“Raised by” below names the package(s) whose source constructs the code (from rg 'ERR_' packages/*/src, tests excluded); mcp re-raises most codes on behalf of the engines and is listed only where it originates one.

Validated first by the RelPath schema (no I/O), then by apply’s containment walk against the real filesystem, and by the gate on every write target.

Code Meaning Raised by
ERR_PATH_NOT_RELATIVE_POSIX leading /, a drive letter, or a backslash in a path schema, apply, gate, migrate v1
ERR_PATH_SEGMENT empty, ., .., trailing dot/space segment, or length out of 1–1024 schema, apply, axm (mapped to the path literal), gate
ERR_PATH_NOT_NFC path is not NFC-normalised schema, apply
ERR_PATH_RESERVED_NAME a segment is a Windows device name (CON, NUL, COM1…) — on every OS schema, apply, gate, path.reservedNames predicate
ERR_PATH_INVALID_CHAR <>:"|?*, a C0 control or DEL in a path (: also rules out NTFS alternate data streams) schema, apply, gate
ERR_PATH_CASE_COLLISION two artifacts (or an artifact and an existing file on a case-insensitive FS) differ only by case apply
ERR_SYMLINK_IN_PATH a symlink or junction in the target’s ancestry, or where a file is expected in verify --tree apply, gate, snapshot
ERR_CONTAINMENT realpath of the target’s directory is outside the root; a snapshot glob containing .. apply, gate, snapshot
ERR_TARGET_TYPE target exists but is a directory or symlink apply
ERR_EXISTS op: create but the target exists (and no applied marker makes it a re-apply) apply
ERR_NOT_FOUND op: delete on an absent path; no journal for a digest (rollback); trust store or keyid missing; an axiom:// resource or stored manifest that does not exist apply, checks (manifest.requireSigned provider error), mcp
Code Meaning Raised by
ERR_BLOB_MISSING no bytes for a digest in blobs, the CAS or a fetched ref; a journal naming a manifest that is not stored (gc) plan, apply, mcp (gc, migrate v1)
ERR_DIGEST_FORMAT not sha256: + 64 lowercase hex schema, apply, checks
ERR_DIGEST_MISMATCH bytes do not hash to the declared digest — a blob, a CAS entry, a fetched ref, a migrate v1 sidecar plan, apply, mcp
ERR_SIZE_MISMATCH decoded size differs from bytes apply, checks
ERR_BLOB_TOO_LARGE a single inline blob (or rendered template, or ref body) exceeds its cap — 256 KiB inline, 32 MiB ref plan, apply, migrate v1
ERR_BUNDLE_TOO_LARGE inline blobs total more than 4 MiB; also any MCP call body over 4 MiB plan, mcp
Code Meaning Raised by
ERR_LOCKED .axiom/lock held by a live process after the wait (30 s for apply, 1 s for gc); details.holder names it apply, mcp (gc)
ERR_ROOT_NOT_ALLOWED requested root is not equal to or inside a --root mcp (roots policy — shared by CLI and server)
ERR_ROOT_REQUIRED no root given and zero or several roots are allowlisted mcp
ERR_ROOT_NOT_DIR root does not exist or is not a directory mcp, apply
ERR_CONFIRM_DIGEST_MISMATCH confirmDigest !== bundle.manifestDigest apply, CLI apply --confirm
ERR_CHECKS_FAILED pre-apply check verdict was not pass (fail or error) apply
ERR_PREIMAGE_CHANGED the tree differs from ManifestBody.preImage at check/first-apply time (details.phase: "prepare"), or a file changed between staging and commit (TOCTOU guard, no phase) apply, checks (manifest.preImage finding), plan
ERR_JOURNAL_CORRUPT journal file unreadable, not JSON or fails schema apply
ERR_EBUSY rename/unlink kept failing (Windows open handle) after 5 retries; also more than 8 concurrent tasks or 16 open plan sessions on the server apply, mcp (tasks)
ERR_ROLLBACK a commit failed and the scoped rollback failed; status: failed, journal left in place; message carries both errors apply
Code Meaning Raised by
ERR_INVALID_PLAN Plan fails PlanSchema (details carry Zod issues with JSON pointers); a .axm semantic error; duplicate path across axiom_plan_add chunks or after migrate v1 normalisation plan, axm, mcp
ERR_INVALID_MANIFEST bundle fails ManifestBundleSchema; a stored manifest that fails it (gc); not a v1 manifest (migrate v1) plan, apply, mcp
ERR_INVALID_PROFILE profile missing, not JSON, name ≠ file stem, extends cycle or missing parent, or fails schema; bad profile name checks
Code Meaning Raised by
ERR_PREDICATE_UNKNOWN CheckRef.predicate is not registered checks
ERR_PREDICATE_PARAMS CheckRef.params fail the predicate’s schema; a CEL function outside the allowlist or an unsafe regex; a Cedar parse error, template or > 256 policies; a guard command that resolves outside <root>/scripts/ or the allowlist checks
ERR_PROVIDER_FAILED a fact provider or predicate threw; CEL/Cedar evaluation error or time budget exceeded; cedar-wasm not installed; unreadable trust store checks
ERR_GUARD_TIMEOUT an external guard exceeded timeoutMs (≤ 15 min); process tree killed checks
ERR_GUARD_OUTPUT guard stdout was not a valid GuardOutput JSON object, or the process could not be spawned checks
ERR_FACT_DISABLED a provider/predicate is disabled by the profile or a CLI gate — guard.external without facts.allowGuards and --allow-guards; a repo-needing predicate with no root — yields verdict: error checks
Code Meaning Raised by
ERR_SIGNATURE_MISSING a trust store exists but the bundle carries no signature at all (axiom verify --root, axiom_manifest_verify) mcp (keys.ts), canon
ERR_SIGNATURE_INVALID signature verification failed — unknown key, bad signature, non-canonical payload, payload/digest mismatch, rollback, unbound/mis-bound envelope — or unusable key material (sign, trust add) mcp, canon, checks
ERR_TRUST_STATE_CORRUPT .axiom/trust/state.json unreadable, not JSON, fails schema, or its HMAC is missing/wrong while state.key exists — never treated as “no state” checks, mcp, apply
Code Meaning Raised by
ERR_EMITTER_UNKNOWN template.emitter is not in the compile-time registry, or no registry was given (details.available) plan
ERR_TEMPLATE_UNKNOWN the emitter has no template of that name (details.available) plan, emitters-web
ERR_TEMPLATE_PARAMS template.params fail the template’s Zod schema (details.issues) plan, emitters-web
Code Meaning Raised by
ERR_PATCH_FORMAT patch.body is not parseable in the declared format (details.format, line) plan, axm
ERR_PATCH_PREIMAGE the file under the root does not hash to patch.preImage, is absent, is not UTF-8, or no root was given (details.expected, actual) plan
ERR_PATCH_NO_MATCH a hunk’s block or @@ anchor did not match exactly once (details.hunk, matches, searchedFromLine, block) plan
Code Meaning Raised by
ERR_GIT_NOT_FOUND no git on PATH apply
ERR_GIT_NOT_REPO git rev-parse --show-toplevel is not the root itself (a subdirectory of a repo is rejected on purpose) apply
ERR_GIT_DIRTY git status --porcelain -- <touched paths> is not empty (details lists them) apply
ERR_GIT_BRANCH_EXISTS refs/heads/<branch> already exists apply
ERR_GIT_BRANCH_INVALID branch name fails the regex or git check-ref-format --branch; no git process is spawned for syntactic rejects apply
ERR_GIT_FAILED any git call exited non-zero or timed out (60 s); first stderr line in the message, last 4 KiB in details.stderr apply
Code Meaning Raised by
ERR_TASK_NOT_FOUND taskId / sessionId unknown to this server process — never created, expired after its TTL (10 min tasks, 30 min idle sessions), or already consumed mcp
ERR_TASK_CANCELLED the task was cancelled (axiom_task_cancel or server stop); also the provider finding a killed guard reports mcp, checks
ERR_PLAN_SESSION_STATE axiom_plan_add on a sealed session, or a chunk that would exceed the session’s 2000-artifact / 64 MiB budget mcp
Code Meaning Raised by
ERR_REF_OFFLINE a ref source compiled without a root, or applied while its blob is not in the CAS plan, apply
ERR_NET_DISABLED ref not in the CAS and --allow-net not given (details.host, redacted uri) plan
ERR_NET_DENIED ref refused by policy: not https: (file: without --allow-file), credentials in the URI, host not in --net-allow plan
ERR_NET_FAILED ref fetch failed: timeout, redirect, network error, non-2xx (details.status) plan
Code Meaning Raised by
ERR_NOT_CANONICAL manifest artifacts/checks not sorted or not unique, or manifestDigest ≠ recomputed hash plan (verifyBundle), apply
ERR_UNSUPPORTED_OP an operation the engine does not implement (axiom_repo_snapshot with followSymlinks: true); in the gate, a write tool whose target cannot be determined mcp (snapshot, gate)
ERR_INTERNAL invariant violation inside AXIOM — a result that fails its own schema, content that vanished between hash and write, a predicate registered twice, a bad --http spec or short token; in the gate, any internal failure (fail-closed). Please report with details all

[!NOTE] Two other ERR_-prefixed strings appear in the source and are not AXIOM codes: Node’s ERR_PARSE_ARGS_* (surfaced as a usage error, exit 2) and ERR_MODULE_NOT_FOUND / ERR_UNKNOWN_BUILTIN_MODULE, which expr.cedar catches when cedar-wasm is absent and turns into ERR_PROVIDER_FAILED.

A CheckReport finding’s id is the check’s id (path.deny, content.noSecrets.awsKey, signature.rollback, repo.requireCompanion.<name>, brivio.<guard>…), not an ERR_*. Only provider failures carry an error code, in facts.code with facts.__provider: true. The gate’s stderr line uses whichever applies. Catalogue: checks.md.


See also

  • Plan format — the schemas whose violations produce the ERR_INVALID_* and ERR_PATH_* codes
  • Apply — the failure modes behind the apply codes
  • Invariants — invariant 4, why the enum is closed
  • Versioning — an error-code change is a major