moxzi
Docs / Reference / Error and diagnostic codes

Error and diagnostic codesalpha

What does this error mean and what do I do about it?

A moxzi diagnostic is an M#### code attached to a source region, a severity and a category, rendered the way moc renders one so editors and habits carry over. The code registry (mops/mo-langutils/src/ErrorCodes.mo, a port of moc's error_codes.ml) lists about 204 error codes and 43 warning codes; 65 are actually emitted — the rest are declared for parity and never raised.

How a diagnostic is printed#

/src/main.mo:4.10-4.19: type error [M0030], type field does not exist in type
  note: ...
PartWhere it comes from
file:l.c-l.cthe message's region
typethe category word; warnings drop it
error / warning / infoDiag.Severity (mops/mo-langutils/src/Diag.mo:36)
[M0030]the code; omitted when empty, and always omitted for info
notesrendered one per line, prefixed note: — usually the inferred type

A build fails when any message has severity #Error (Diag_hasErrors, Diag.mo:253). The CLI's renderer is render_diag in moxzi/src/compile.rs:293; the JSON form emits message, code, level, spans, notes.

The codes you will actually hit#

CodeMeaningWhat to do
M0220this actor or actor class should be declared persistentadd persistent, or build with --default-persistent-actors
M0096expression of type T cannot produce expected type Uthe generic check-mode mismatch; read the note for the inferred type
M0057unbound variabletypo, missing import, or a name not in scope
M0026unbound variable in a paththe module qualifier does not resolve
M0029unbound typethe type name does not resolve
M0028 / M0030field / type field does not existwrong qualifier or wrong package version
M0020unresolved importa missing mo: package or a wrong relative path
M0006import cyclebreak the cycle; moxzi names the path
M0016cannot use x before y has been definedreorder, or wrap in a function
M0055cannot infer type of forward variablea binding without a type annotation reads a value declared later: annotate it (var v : Nat = seed(i)) or reorder
M0157block contains non-productive definitiona type defined only in terms of itself (type T = T), in any body — actor, object, module or block
M0001unexpected tokena syntax error. i<22 is one: < is a comparison only with spaces on both sides, otherwise a type-argument bracket, as in moc — write i < 22
M0031 / M0032shared function has a non-shared parameter / return typeonly shared types cross a message boundary
M0072field does not exist in {…}the record literal is missing it
M0073expected mutable assignment targetdeclare the binding var
M0077a shared function is only allowed as a public field of an actormove it into the actor
M0082expected iterable type.vals() / .keys()
M0088expected async typeyou are awaiting something that is not a future
M0037 / M0038misplaced await/async; try enclosing in an async function/expression
M0064misplaced !there is no enclosing do ? { }
M0097expected function typeyou are calling a non-function
M0102 / M0103cannot infer the type of a wildcard / variableadd an annotation
M0112–M0117pattern cannot consume the expected typetuple, option, object, variant, operator and general forms
M0119show is not defined for this typedebug_show needs a showable type
M0124 / M0125public actor field has a non-shared function type / is not a manifest function
M0141an actor or actor class must be the only non-imported declarationmove declarations into the actor body
M0175to_candid argument must have a shared type
M0184 / M0261cannot infer the type of this or-/and-patternannotate it
M0189 / M0260different bindings in pattern alternatives / bound in both and-pattern legs
M0225a mixin cannot be an entry pointinclude it in an actor
M0233cannot resolve implicit argumentpass it explicitly
M0238break/continue outside a loop

Emission sites are almost entirely in mops/mo-frontend/src/Typing.mo, with Static.mo, Definedness.mo, Resolve.mo and bin/compiler-canister/Main.mo supplying the rest.

Codes with moxzi-specific wording#

Codemoxzi's wordingNote
M0069non-toplevel actor; an actor can only be declared at the toplevel of a programmoxzi emits M0069 alone where moc also reports M0037 and M0038 — a deliberate divergence, gated by scripts/nontoplevel_actor_matrix.sh
M0057 (prim gate)unbound variable prim / help: did you mean variable Prim?an authorization gate, not a type error: prim is only available with MOC_UNLOCK_PRIM
M0096 (arity form)call supplies N arguments but the function expects M (with K implicit param(s)); implicit insertion cannot reconcile the differencea second, more specific M0096 at Main.mo:2710
M0250a stable variable under --enhanced-migration carries an initializerdelete it; the migration chain supplies the value
M0267a stable field the migration chain cannot explain, measured against --stable-baseline — the message names the boundary it was measured at (initial actor or upgrade resuming after migration m2``)write a migration that produces the field, or correct the baseline
M0169 / M0170 / M0216the upgrade-compatibility verdicts (dropped variable / incompatible type / silent data loss), from moxzi stable-compatible and the baseline checksame meanings as moc
M9000unimplemented: <what>moxzi-only. Not a program error — a compiler feature that is not ported. Report it

Warnings#

Severity is a property of the message, not of the code. Warnings print on successful builds, before the provenance line. Eight are emitted today:

CodeMeaning
M0089redundant ignore on an operand already of type ()
M0145this pattern does not cover every value of its type (a switch or let that can fail)
M0146this pattern case is never matched
M0194unused identifier — blocks, match arms and loops (function parameters, top-level ids and object fields do not warn yet); an import used only in types counts as used, as in moc
M0198unused field binding in a pattern
M0254a stable field the migration chain does not produce (without --stable-baseline; with one it becomes error M0267)
M0265mixin capability mismatch
M0266a float literal with more precision than Float can represent, naming what it rounds to

moc emits more warning codes than these; the rest are absent here, which is a real stderr difference against moc (called out in scripts/shared_type_matrix.sh).

Lint levels exist (mops/mo-sys/src/Flags.mo:47, #Allow/#Warn/#Error). Four codes are suppressed by default: M0223, M0235, M0236, M0237, matching moc's defaults.

M0000 is overloaded#

moxzi uses M0000 for several things moc splits up: parse errors (moc uses M0001), filesystem and import failures, prelude and desugar failures, job authorization refusals, and IR subtype violations (Ill-typed intermediate code: subtype violation). If you are matching on diagnostics programmatically, match the text as well as the code — the corpus harness does exactly that.

Runtime errors#

Traps and rejects, not compile-time diagnostics. Formatted in one place, ic_reject_message at moxzi/runtime/src/machine.rs:328, matching the IC's first line.

FormWhen
IC0503: Error from Canister <id>: Canister called ic0.trap with message: '<t>'.an explicit ic0.trap — most Motoko traps
IC0502: Error from Canister <id>: Canister trapped: <text>.a recognised wasm trap; currently only stack overflow

Reject codes follow the IC's numbering (moxzi/runtime/src/sys.rs:28): 1 SYS_FATAL, 2 SYS_TRANSIENT, 3 DESTINATION_INVALID, 4 CANISTER_REJECT, 5 CANISTER_ERROR, 6 SYS_UNKNOWN.

Two messages you will meet that are not codes at all:

MessageSource
self-calls nested more than 512 deep (a runaway async chain?)the shared call-depth cap; the same in the browser and natively
Canister exceeded the limit of 40000000000 instructions for single message executionthe replica, on-chain only. moxzid kills the message at its own --instruction-limit instead

Things this page cannot tell you#

Code-to-explanation prose exists for only a handful of codes (M0003, M0037 and a few others carry a long-form .md flag in the registry). There is no per-code explainer command. If a diagnostic is unclear, that is a bug worth filing — see Reporting a bug.

Next#

On this pageHow a diagnostic is printedThe codes you will actually hitCodes with moxzi-specific wordingWarningsM0000 is overloadedRuntime errorsThings this page cannot tell youNext