Error Codes
Purpose #
The full map of AidoError.code ↔ exit code ↔ situation. Authoritative source: .docs/docs/specs/cli-reference.md §10.2.
Conventions #
- Codes are
SCREAMING_SNAKE_CASE. - Prefix indicates category where one applies:
PREREQ_*,ADAPTER_*,MCP_*,FS_*. - Codes are stable across releases — new codes added; existing codes never renamed.
- This table mirrors the canonical
ErrorCodeenum in@aidokit/core(packages/core/src/error.ts), which is the single source of truth (ADR-0012). It lists exactly the enum's members. State and internal codes have no dedicated exit group and map to1(generic).
Reserved error codes #
| Code | Exit | Category | Meaning |
|---|---|---|---|
BAD_INVOCATION |
2 | invocation | Argument parsing / invocation failure |
PREREQ_MISSING |
10 | prereq | Required prerequisite not installed |
ADAPTER_NOT_FOUND |
11 | adapter | Adapter package not installed or unresolvable |
UNKNOWN_ADAPTER |
11 | adapter | Requested adapter id is not registered |
STACK_PACK_NOT_FOUND |
12 | stack pack | Stack pack not installed |
CONFORMANCE_FAILED |
13 | conformance | Harness or doctor check failed |
FILE_WRITE_FAILED |
20 | filesystem | File write error |
POLICY_READ_FAILED |
20 | filesystem | .aidokit/policy.json could not be read/parsed |
MCP_INSTALL_FAILED |
21 | MCP | MCP registration command exited non-zero |
MIGRATION_FAILED |
30 | migration | Migration script error |
USER_CANCELLED |
40 | user | User declined an interactive prompt |
SCHEMA_VALIDATION_FAILED |
60 | validation | Payload failed Zod schema validation |
INVALID_ARTIFACT |
60 | validation | Artifact failed validation |
SCHEMA_NOT_FOUND |
60 | validation | Named schema could not be resolved |
POLICY_INVALID |
60 | validation | .aidokit/policy.json failed schema validation |
INTERPOLATION_MISSING_VAR |
1 | internal | Template variable referenced but not supplied |
NOT_INITIALISED |
1 | state | Project has no .aidokit/ state (run aidokit init first) |
CORRUPT_STATE |
1 | state | Malformed state file (e.g. agent-artifacts/<id>/state.json) |
INTERNAL_ERROR |
1 | internal | Unexpected internal failure (uncategorised) |
v1.x finding codes — aidokit verify facets #
These codes are reported by aidokit verify facets. Severity is error unless noted. See ADR-0018.
| Code(s) | Facet | Meaning |
|---|---|---|
SECRET_AWS_ACCESS_KEY, SECRET_AWS_SECRET_KEY, SECRET_GITHUB_PAT, SECRET_SLACK_TOKEN, SECRET_STRIPE_KEY, SECRET_ANTHROPIC_API_KEY, SECRET_OPENAI_API_KEY, SECRET_NPM_TOKEN, SECRET_GCP_SA_JSON, SECRET_JWT, SECRET_SSH_PRIVATE_KEY |
--secrets |
Bundled provider-specific credential patterns matched in scanned content. |
SECRET_HIGH_ENTROPY |
--secrets |
Shannon-entropy fallback hit — possible unknown-format secret. |
BUDGET_EXCEEDED |
--budget |
Computed task spend exceeds policy.budget.maxUsdPerTask. |
BUDGET_NEAR_LIMIT |
--budget |
Within configurable warning threshold of the budget cap. Severity warn. |
BUDGET_LEDGER_MISSING |
--budget |
agent-artifacts/metrics/events.jsonl token ledger absent. |
DEP_NEW_UNAPPROVED |
--deps |
New dependency outside allowedScopes and no justification block. |
DEP_NEW_UNJUSTIFIED |
--deps |
New dependency added without a change-summary ## Dependencies section. |
DEP_VERSION_DOWNGRADE |
--deps |
Dependency version moved backwards. |
LICENSE_HEADER_MISSING |
--license |
SPDX header required (requireHeaders: true) but missing. |
LICENSE_INCOMPATIBLE |
--license |
Detected license incompatible with project license. |
LICENSE_FORBIDDEN |
--license |
Detected license in forbidden list. |
LICENSE_UNKNOWN |
--license |
License could not be resolved. |
LOOP_CAP_EXCEEDED |
--loop-cap |
Task iteration count exceeds policy.loopCap.maxIterations. |
LOOP_CAP_NEAR_LIMIT |
--loop-cap |
Within warning threshold of the loop cap. Severity warn. |
FACET_NOT_IMPLEMENTED |
all | Facet is stubbed (returns deferred-impl signal). |
v1.x finding codes — aidokit doctor #
| Code | Check | Meaning |
|---|---|---|
MCP_QUARANTINE_SKILL_MISSING |
core/MCP | An MCP server marked untrustedOutput: true is enabled without the quarantining-untrusted-output skill present. See ADR-0019. |
MODEL_LOCK_MISSING |
--model-drift |
.aidokit/model.lock absent. |
MODEL_DRIFT_DETECTED |
--model-drift |
Declared adapter cliVersion does not match .aidokit/model.lock. |
HYGIENE_NO_SCRATCHPAD |
--hygiene |
Active task brief references a scratchpad that does not exist. |
HYGIENE_STALE_SCRATCHPAD |
--hygiene |
Scratchpad exists but has not been touched in the freshness window. |
HYGIENE_DRIFT |
--hygiene |
Brief↔commit drift (committed code without a corresponding brief, or vice versa). |
doc-drift |
--drift (semantic) |
Broken file reference or missing symbol reference in docs. Severity warn. |
RULES_DUPLICATE_BLOCK |
--rules |
An identical block (≥6 words) appears two or more times across or within rules files. Severity warn. |
RULES_OVERSIZED |
--rules |
A rules file exceeds the 400-line budget. Severity warn. |
RULES_CONFLICT_DIRECTIVE |
--rules |
Affirmative vs. negated directives on the same keyword across rules files. Severity warn. |
RULES_OK |
--rules |
No rules-file issues found. Severity pass. |
CONFLICT_DIRECTIVE |
--conflicts |
Contradictory directives on the same keyword across rules files, engine skills, and/or task briefs. Severity warn. |
CONFLICT_OK |
--conflicts |
No conflicting directives found across rules, skills, and task briefs. Severity pass. |
BUDGET_MAP |
--budget-map |
Per-role context budget summary: line/byte counts plus heuristic skill/MCP/doc reference counts for a <engine>/agents/*.md file. Severity pass (informational). |
BUDGET_OVERSIZED |
--budget-map |
A role agent file exceeds the 300-line budget. Severity warn. |
MODEL_POLICY_ABSENT |
--model-policy |
No .aidokit/model-policy.json present; model selection is left to the agent runtime. Severity pass (informational). |
MODEL_POLICY_INVALID |
--model-policy |
.aidokit/model-policy.json is present but is not valid JSON or fails the model-policy schema (Zod error included). Severity warn. |
MODEL_POLICY_OK |
--model-policy |
.aidokit/model-policy.json is present and valid. Severity pass. |
Exit-code groups #
From .docs/docs/specs/cli-reference.md §8:
| Code | Group |
|---|---|
| 0 | Success |
| 1 | Generic error |
| 2 | Bad invocation |
| 10 | Prereq missing |
| 11 | Adapter |
| 12 | Stack pack |
| 13 | Conformance |
| 20 | Filesystem |
| 21 | MCP |
| 30 | Migration |
| 40 | User |
| 50 | Network |
| 60 | Validation |
| 70 | Conflict |
The 50 (Network) and 70 (Conflict) groups are reserved in the taxonomy for
future and adapter-introduced codes; no canonical ErrorCode maps to them today.
Envelope shape #
export class AidoError extends Error {
constructor(
public code: string, // e.g. 'PREREQ_MISSING'
message: string, // human-readable
public details?: Record<string, unknown>,
public hint?: string, // suggested fix
) { super(message); }
}
--json mode emits:
{
"ok": false,
"command": "init",
"error": {
"code": "PREREQ_MISSING",
"exitCode": 10,
"message": "Prerequisite missing: Claude Code",
"details": { "prereq": "claude-code", "minVersion": "2.1.32" },
"hint": "Install Claude Code via: curl -fsSL claude.ai/install.sh | bash"
}
}
Human mode formats the same envelope as:
✘ Prerequisite missing: Claude Code (PREREQ_MISSING)
Detected: No `claude` command found on PATH.
Hint: Install Claude Code via:
curl -fsSL claude.ai/install.sh | bash
Or set --skip-prereq-check to bypass.
Adding a new error code #
- Add the constant to
packages/core/src/error.tsErrorCodeconstants. - Map it to an exit code in
packages/cli/src/exit-codes.ts. - Document the new code in this file and in .docs/docs/specs/cli-reference.md §10.2.
- Bump
@aidokit/coreminor (new code is additive).