Skip to main content
Every error Nika emits is a typed structure with a stable code, a category, and a transient flag the retry machinery reads. The format is NIKA-<NAMESPACE>-<NNN> — an optional sub-namespace self-documents builtin errors (NIKA-BUILTIN-WAIT-001). The full grammar:
^NIKA-[A-Z]{2,9}(-[A-Z][A-Z0-9_]{1,15})?-[0-9]{3}$
Canonical source: spec/05-errors.md owns the taxonomy — engines derive from it, never the reverse. The machine-readable registry lives in the spec’s canon.yaml and is also served as JSON at nika.sh/errors/catalog.json. The tables below are generated from that registry.

The error shape

{
  "code": "NIKA-INFER-001",
  "category": "provider_error",
  "message": "Anthropic API returned 503 service unavailable",
  "transient": true,
  "details": { "provider": "anthropic", "status_code": 503 },
  "task_id": "research",
  "attempt": 2
}
transient: true means a retry might succeed — retry: only fires on transient errors (unless on_codes: widens it). on_error: catches the final error either way, and on_error.on_codes routes recovery by exact code.

Categories

CategoryMeaning
parse_errorWorkflow YAML is malformed or invalid
validation_errorWorkflow violates a spec rule (cycle · unknown field · …)
variable_errorReference to undefined variable or invalid path
provider_errorLLM provider returned an error
network_errorNetwork failure (DNS · TCP · TLS · timeout)
tool_errorBuiltin or MCP tool returned an error
process_errorexec: subprocess failure (non-zero exit · spawn)
budget_errorAn agent: loop budget exhausted (max_turns · max_tokens_total)
security_errorSSRF · blocklist · capability denied
timeout_errorTask or step exceeded its timeout
cancelledWorkflow or task cancelled
internal_errorEngine bug · unexpected state

The 28 registered codes (v0.1 normative floor)

A conformant engine emits exactly these codes for these failures. Engines may add codes within a namespace’s 001-099 range — never repurpose one.
CodeFailureCategorytransient
NIKA-PARSE-001the YAML itself does not parse (syntax error)parse_errorfalse
NIKA-PARSE-002missing envelope field (nika: / workflow: / non-empty tasks:)validation_errorfalse
NIKA-PARSE-003nika: version marker is not exactly v1parse_errorfalse
NIKA-PARSE-004workflow: id violates ^[a-z][a-z0-9-]*$validation_errorfalse
NIKA-PARSE-005unknown field — strict mode rejects anything outside the closed v1 setvalidation_errorfalse
NIKA-PARSE-006task id violates ^[a-z][a-z0-9_]*$ (snake_case · CEL-safe · no hyphens)validation_errorfalse
NIKA-PARSE-007duplicate task id within the workflowvalidation_errorfalse
NIKA-PARSE-008task declares no verb — exactly one of infer/exec/invoke/agent requiredvalidation_errorfalse
NIKA-PARSE-009task declares multiple verbs — exactly one requiredvalidation_errorfalse
NIKA-PARSE-010timeout: violates the quoted Go-duration contract (positive · max 24h · descending units)validation_errorfalse
NIKA-PARSE-011retry: block violates the spec shapevalidation_errorfalse
NIKA-PARSE-012on_error: block violates the spec shape (fields mutually exclusive)validation_errorfalse
NIKA-PARSE-013with:/output: binding uses a reserved name (output · status · error · started_at · ended_at · duration_ms)validation_errorfalse
NIKA-PARSE-014secrets: entry is not a store reference — inline literals forbiddenvalidation_errorfalse
NIKA-PARSE-015typed vars: declaration malformed (type in string/number/integer/boolean/array/object)validation_errorfalse
NIKA-PARSE-017duplicate mapping key — no silent last-winsvalidation_errorfalse
NIKA-PARSE-018missing required field in a verb body (infer.prompt · exec.command · invoke.tool)validation_errorfalse
NIKA-PARSE-019generic structural validation — wrong YAML shape for a fieldvalidation_errorfalse
NIKA-DAG-001cycle in depends_on (incl. self-dependency)validation_errorfalse
NIKA-DAG-002depends_on references an undeclared taskvalidation_errorfalse
NIKA-DAG-003a tasks.X reference with no declared edgevalidation_errorfalse
NIKA-DAG-004on_error.recover references a task downstream of the declaring task (await would deadlock)validation_errorfalse
NIKA-VAR-001unresolved reference (unknown namespace entry · undeclared env/vars key)variable_errorfalse
NIKA-VAR-002binding cardinality — a jq binding emitted zero or multiple valuesvariable_errorfalse
NIKA-VAR-003provably-invalid path into a declared schema (static walk)validation_errorfalse
NIKA-VAR-004jq runtime error while evaluating a bindingvariable_errorfalse
NIKA-VAR-005static expression violation — outside cel-subset/0.1 · chained relation · unknown function · non-boolean when: root · jq compile errorvalidation_errorfalse
NIKA-VAR-006expression type error at evaluation — cross-type compare · non-boolean when: value · for_each over a non-arrayvariable_errorfalse
NIKA-VAR-007bytes value substituted into a string positionvariable_errorfalse
NIKA-VAR-008unclosed ${{ openervalidation_errorfalse
NIKA-VAR-009typed outputs value did not match its declared type: at run end (the output half of the callable contract)validation_errorfalse
NIKA-INFER-001provider call failed (HTTP error · provider refusal)provider_errorengine-assessed
NIKA-INFER-002structured output failed schema validation (after any engine-internal retries)validation_errorfalse
NIKA-EXEC-001non-zero exit code (default capture modes)process_errorfalse
NIKA-EXEC-002spawn failure (command not found · permission)process_errorfalse
NIKA-INVOKE-001unknown tool (unresolvable nika:/mcp: id)validation_errorfalse
NIKA-INVOKE-002tool args failed the tool’s schemavalidation_errorfalse
NIKA-AGENT-001max_turns exhausted before completionbudget_errorfalse
NIKA-AGENT-002max_tokens_total exhausted before completionbudget_errorfalse
NIKA-MCP-001MCP server not configured / not reachable at call timetool_errorengine-assessed
NIKA-MCP-002MCP tool call failed (transport · tool-side error)tool_errorengine-assessed
NIKA-SEC-001exec: blocklist hitsecurity_errorfalse
NIKA-SEC-002agent tool call outside the tools: whitelistsecurity_errorfalse
NIKA-SEC-003run-recursion bound — nested-run depth exceeded OR self-launching workflowsecurity_errorfalse
NIKA-SEC-004effect outside the declared permits: capability boundary (fs/net/exec/tool)security_errorfalse
NIKA-SEC-005SSRF block — a nika:fetch/nika:notify URL resolves to a loopback/private/link-local/metadata target (always-on engine floor · independent of permits:)security_errorfalse
NIKA-TIMEOUT-001task (or for_each iteration) exceeded timeout:timeout_errorfalse
NIKA-CANCEL-001task cancelled (workflow failure gate · user cancellation)cancelledfalse
NIKA-BUILTIN-001builtin invoke violates its statically-checkable arg contract (e.g. nika:fetch without url: · nika:jq arg shape)validation_errorfalse
NIKA-BUILTIN-DONE-001nika:done invoked outside an agent: loopvalidation_errorfalse

Namespaces

NamespaceScopeRange
NIKA-AGENTagent: verb errors001-099
NIKA-BUILTINBuiltin tool errors · per-builtin sub-namespace001-099
NIKA-CANCELTask or workflow cancellation001-099
NIKA-DAGDAG topology · cycles · invalid deps001-099
NIKA-EXECexec: verb errors001-099
NIKA-IMPLEngine internal errors001-099
NIKA-INFERinfer: verb errors001-099
NIKA-INVOKEinvoke: verb errors001-099
NIKA-MCPMCP client errors001-099
NIKA-PARSEYAML parse + envelope validation001-099
NIKA-PROVIDERProvider adapter errors001-099
NIKA-SECSecurity policy violations (SSRF · blocklist)001-099
NIKA-TIMEOUTTask or step timeouts001-099
NIKA-VARVariable resolution failures001-099
Builtin errors use a per-builtin sub-namespace — each builtin owns its own 001-099 (NIKA-BUILTIN-FETCH-001 is the fetch tool’s network/extraction failure). Underscore-named builtins encode naturally: NIKA-BUILTIN-JSON_MERGE_PATCH-001.

Routing on codes

# Retry ONLY on the fetch network error · fixed 30s backoff
retry:
  max_attempts: 5
  backoff_strategy: fixed
  backoff_ms: 30000
  on_codes: [NIKA-BUILTIN-FETCH-001]

# Recover ONLY on timeout · any other code still fails
on_error:
  on_codes: [NIKA-TIMEOUT-001]
  recover: { stale: true, items: [] }
on_error.skip preserves the original error at tasks.X.error — a downstream task can branch on ${{ tasks.X.error.code }} while the status reads skipped.

The full error model

Retry policies, backoff strategies, recovery semantics, and the gate-based failure propagation rules — spec/05-errors.md.