Skip to content

Diagnostics

Use this when you need to decode an ILO-* error code, understand fixSafety, or look up a repair plan.

ilo verifies programs before execution. When verification fails, you get a compact error code. Runtime failures emit codes too. Use ilo --explain ILO-XNNN for the full explanation.

Every diagnostic carries a fixSafety tag that tells an agent how aggressively it may auto-correct the code without re-asking the user:

fixSafetyMeaningAgent behaviour
safeMechanical, no semantic changeApply the suggested fix without confirmation.
likelyAlmost always correct, but reads contextApply and continue; surface a one-line note.
riskyMultiple valid repairs existPropose and ask for confirmation.
manualRequires human judgmentSurface the diagnostic and stop.

Diagnostics with a structured repair plan attach a JSON block to the JSON-mode (-j) error. The plan lists ordered edits the agent can apply mechanically:

JSON
{
"code": "ILO-T004",
"message": "undefined variable 'y'",
"fixSafety": "likely",
"repair": [
{"kind": "rename", "from": "y", "to": "x"}
]
}

See ilo --explain ILO-XNNN for the per-code repair contract.

Every diagnostic ilo emits has the shape ILO-<letter><digits>. The letter is the namespace - the phase that raised the diagnostic - so agents and tools can route on prefix without parsing the message. Numeric ranges are reserved per namespace with generous gaps, so future codes slot in cleanly. A cross-engine regression test enforces this contract.

RangeLetterAreaStatus
ILO-L000-099LLexer / tokenisationactive
ILO-P100-199PParser / syntaxactive
ILO-N200-299NNames / resolutionreserved
ILO-I300-399IImportsreserved
ILO-T400-499TTypesactive
ILO-V500-599VVerifier (post-type checks)reserved
ILO-R600-699RRuntimeactive
ILO-D700-799DDeprecation warningsreserved
ILO-E800-899EEngine-specific limitationsreserved
ILO-S900-999SSkill / spec systemreserved

Historical codes stay valid. ilo shipped with flat numbering inside each namespace (ILO-L001, ILO-P001, ILO-T001, ILO-R001, ILO-W001, all starting at 001). Those codes remain valid forever - agents and pinned tool configs depend on them. The hundreds-block allocation applies to new codes going forward.

Reserved namespaces. N, I, V, D, E, S carry no codes today. They are forward declarations so the first code in each category lands in its own range without conflicting with the active namespaces. D is earmarked for deprecation warnings: when a feature is scheduled for removal it emits an ILO-D7xx warning at compile time without failing the build.

CodeDescription
ILO-L001Unexpected character
ILO-L002Underscore in identifier, use hyphens
ILO-L003Uppercase identifier, use lowercase
CodeDescription
ILO-P001Unexpected token at top level
ILO-P002Unexpected end of file at top level
ILO-P003Unexpected token
ILO-P004Unexpected end of file
ILO-P005Expected identifier, got token
ILO-P006Expected identifier, got end of file
ILO-P007Expected type annotation, got token
ILO-P008Expected type annotation, got end of file
ILO-P009Expected expression, got token
ILO-P010Expected expression, got end of file
ILO-P011Expected pattern, got token
ILO-P012Expected pattern, got end of file
ILO-P013Expected number literal, got token
ILO-P014Expected number literal, got end of file
ILO-P015Expected tool description string
ILO-P016Unexpected token after braceless guard body
ILO-P017use-import failed
ILO-P018Variadic builtin not in trailing position
ILO-P019use-import name not found
ILO-P020Incomplete function header
ILO-P021Double-minus prefix-binop trap rejected - - -<op> a b <op> c d for <op> ∈ {+, *, /} is rejected at parse time because it silently miscompiles into -(a-b). Use - 0 +*a b *c d or bind the inner result first.
ILO-P101List-literal element starts with a variadic builtin (fmt, fmt2) followed by operands - rejected at parse time because the bare form would fall through as multiple elements with the builtin name as an undefined Ref. Wrap the call in parens ([k (fmt2 v 2)]) or bind first (s=fmt2 v 2;[k s]).
CodeDescription
ILO-T001Duplicate type definition
ILO-T002Duplicate function or tool definition
ILO-T003Undefined type
ILO-T004Undefined variable
ILO-T005Undefined function
ILO-T006Arity mismatch
ILO-T007Type mismatch at call site
ILO-T008Return type mismatch
ILO-T009Arithmetic operator type error
ILO-T010Comparison operator type error
ILO-T011Append (+=) type error
ILO-T012Negate type error
ILO-T013Builtin argument type error
ILO-T014Foreach collection type error
ILO-T015Record missing field
ILO-T016Record unknown field
ILO-T017Record field type mismatch
ILO-T018Field access on non-record type
ILO-T019Field not found on type
ILO-T020with on non-record type
ILO-T021with field not found
ILO-T022with field type mismatch
ILO-T023Index access on non-list type
ILO-T024Non-exhaustive match
ILO-T025! used on non-Result call
ILO-T026! used in non-Result function
ILO-T027Braceless guard body looks like a function name
ILO-T028brk/cnt used outside a loop
ILO-T029Unreachable code
ILO-T030Circular type alias
ILO-T031Type alias shadows builtin
ILO-T032Bare fmt result is discarded
ILO-T033Bare mutation-shaped builtin result is discarded
ILO-T034! / !! used on a non-callable value
ILO-T035Function exceeds the 256-register VM cap
ILO-T036Call requires too many register slots (VM cap)
CodeDescription
ILO-W001Guard without else inside loop (retired)
CodeDescription
ILO-R001Undefined variable at runtime
ILO-R002Undefined function at runtime
ILO-R003Division by zero
ILO-R004Runtime type error
ILO-R005Field not found at runtime
ILO-R006List index out of bounds
ILO-R007foreach requires a list
ILO-R008with requires a record
ILO-R009Builtin argument error at runtime
ILO-R010Compile error: undefined variable
ILO-R011Compile error: undefined function
ILO-R012No functions defined
ILO-R013Internal VM error
ILO-R014Auto-unwrap propagated Err / nil
ILO-R026Panic-unwrap on Err / nil
ILO-R099Internal runtime error

Reserved range. When a feature is scheduled for removal, ilo emits an ILO-D7xx warning at compile time without failing the build. No codes allocated yet - the first ILO-D### ships with the first feature deprecation.

Reserved range for diagnostics that come from a particular execution engine (VM register caps surfaced ahead of time, JIT-unsupported opcode, AOT constraint). No ILO-E### codes yet.

Reserved range for skill-bundle loader errors, manifest issues, spec-link breaks. No codes yet.

Compact error codes mean agents spend fewer tokens reading error messages and correct faster.