Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Recovery

This page answers: I see a diagnostic — what does it mean and what do I do?

This page covers the most common diagnostics with concrete recovery actions. For the full enumeration, see Appendix C. For long-form explanations of any code, run ox explain <code>.

Resolution + import errors

OE0101 — Unresolved name

What it means: a name doesn’t resolve to anything in scope. Most common cause: missing use import.

Recovery:

  • If the name is a primitive (Nat, Int, Real, Bool, String, Decimal, Money, Date, etc.): add use std::math::<Name>; (no implicit prelude — see RFD-0014).
  • If it’s a foundational-ontology metatype (kind, role, phase, …): add use ufo::prelude::*; (or your foundational-ontology’s prelude).
  • If it’s from a sibling module: add use crate::path::to::Name;.
  • If it’s from another package: ensure the package is in ox.toml [dependencies], then use <package>::path::to::Name;.

OE0102 — Ambiguous import

Two use statements bring the same name into scope. Pick one or rename via as.

OE0103 — Cyclic module dependency

Module A imports B which imports A (transitively). Restructure to break the cycle — usually one of the modules should host the shared declarations and the others import from it.

Type system + structural

OE0201 — Concept used as relation, or vice versa

You wrote Person(alice, bob) but Person is a concept (1-ary), not a relation (2-ary). Or you wrote works_at(alice) but works_at is a relation (2-ary). Check the declared arity.

OE0203 — Non-exhaustive match or cardinality violation

For match: add a wildcard arm or a guardless named arm to handle remaining cases. For cardinality: a relation with cardinality: 1..1 was instantiated zero or two-or-more times for the same source.

OE0206 — Duplicate declaration

Two declarations share a qualified name. Rename one, or move one to a different module.

OE0207 — Mixed-strength rules on same head

You have pub strict foo(X) :- ... and pub derive foo(X) :- ... for the same head. Pick one strength; same-head rules must agree on whether they’re strict or defeasible.

OE0208compute call arg-count mismatch

The compute is declared with N parameters; you called it with M. Match the signature.

OE0210 — Recursive compute-call cycle

Compute A calls B which calls A. Refactor to break the cycle (often via a derive rule that captures the recurrence pattern).

OE0211derive head’s consequence atoms cannot lower

The rule’s head is structurally invalid (often: a head atom references a concept the body doesn’t bind, or the head shape doesn’t match a known consequence form). Check that every variable in the head is bound by a body atom.

Meta-property and metatype

OE0603 — Metaxis value type mismatch

A metatype <T> = { axis = <literal> } assignment has a literal whose type doesn’t match the axis’s declared type. If the axis is : Nat, the value must be a non-negative integer literal.

OE0604 — Tier violation

An expression’s natural tier exceeds the surrounding #dec(tier:...) annotation. Either escalate the surrounding tier or rewrite the expression to fit.

OE0605 — Unknown metatype

A declaration references a metatype name that isn’t in scope. Common causes:

  1. Missing use ufo::prelude::*; (or whichever foundational-ontology package).
  2. Typo in the metatype name.
  3. The metatype was renamed (check the package’s CHANGELOG).

OE0606 — Metaxis refinement violation

A metaxis carries a where { ... } refinement and a value being assigned doesn’t satisfy it.

Test framework

OE0213expect references unknown diagnostic code

The code in expect { diagnostic OE#### } doesn’t exist. Verify against Appendix C.

OE0214 / OE0215 / OE0216 / OE0218 — Frame conflicts

OE0214: using <name> references an unresolved frame. OE0215: two composed frames declare the same-named member. OE0216: an inline fixture redeclares a frame member. OE0218: frame include chain forms a cycle.

For 0215/0216: rename one of the conflicting members. For 0218: break the include cycle.

Decorator + recognizer

OE0229 — Unknown decorator

The decorator name doesn’t resolve. Same recovery shape as OE0101 — usually a missing use.

OE0230 / OE0231 / OE0234 — Decorator arity / target / argument-type mismatch

Check the decorator’s declaration for expected arity, target type, and argument types.

OE0232 — Hint-body mismatch in recognized shape

The decorator’s lowers_to: <shape> claims a shape the body doesn’t match. Either fix the body to match or change the lowering hint.

OE0233 — Tier-clause divergence

A decorator’s tier annotation conflicts with an inferred tier. Pick one.

What to do when none of these match

  1. Run ox explain <code> for the canonical explanation + suggested fix.
  2. Check Appendix C for the full code reference.
  3. Look at the source span — the diagnostic anchors at the offending location.
  4. If the message is unclear, the diagnostic message itself is a bug — file an issue (the message must stand on its own).

See also