Errors reference
Errors are the developer's contract with the pipeline. There are two typed
families, both carrying a stable, switchable .code and a .loc. This page lists every code, the stage that throws it, and the
fix.
The two families
- Parse —
WitError(thrown as its subclassParseError),.code: ErrorCodeName, 20 codes. Thrown byparse. - Runtime —
RuntimeError(base), with subclassesResolverError(resolve) andExpanderError(expand),.code: RuntimeErrorCodeName, 17 codes.RuntimeErrorCodeis exported for switching.
Both extend the same shape, so one instanceof per family catches
everything:
import { WitError } from '@witlang/parser';
import { RuntimeError } from '@witlang/runtime';
try { /* parse → resolve → expand → render */ }
catch (err) {
if (err instanceof WitError || err instanceof RuntimeError) {
console.error(`${err.loc.line}:${err.loc.col}: ${err.code}: ${err.message}`);
} else throw err;
}Parser codes — WitError
All thrown during parse. Cause and fix for each:
E_UNCLOSED_NODE— a use that opens a block never closes (@asideon its own line, noaside@). Only uses that take a body need a close. Fix: add the close.E_UNCLOSED_COMMENT— a~~block comment without~~/. Close it.E_UNCLOSED_DEFINITION— a#nameblock without itsname#, or a value block without!!.E_UNCLOSED_PAREN— a@x(parameter list not closed before the next blank line. Add the).E_UNCLOSED_STATEMENT—(if …)or(each …)without(end).E_UNCLOSED_COLLECTION,E_UNCLOSED_SCRIPT,E_UNCLOSED_RAW_NODE— a[,<%or@@nameleft open. Add],%>orname@@.E_UNTERMINATED_STRING— a quoted value with no closing quote.E_MISMATCHED_CLOSE— inside a node, a close that pairs with no open (@section … aside@ … section@). Match the opener's name.E_MALFORMED_RECORD— a{ … }record that is notkey: valuepairs, including the removed 0.2 separator.E_MALFORMED_FORM_FIELD— a line that is notkey: valueinside a form-fill data definition (#weil:followed by field lines and!!).E_MALFORMED_STATEMENT— a statement other than(if @path …)/(each @path as name), including the removed 0.2 comparison word. Writeis.E_MALFORMED_HEADER— a header entry that is not a name orliteral name(#x(a, b c)).E_RESERVED_PARAM— a header parameter namedbody, which is reserved for::body::.E_RESERVED_FIELD— a record field namedindex,countorlast, reserved for loop positions.E_CONDITIONAL_DEFINITION— a definition inside(if …)or(each …). Put the condition inside the definition.E_BODY_WITHOUT_SLOT— a closed use of a definition that has no::body::(@sig With thanks. sig@). Drop the close, or add::body::to the definition.E_PIPE_SYNTAX_REMOVED— a 0.2 pipe parameter or capture list.E_REMOVED_SYNTAX— a 0.2 record-argument call.
For the two removed-syntax codes, run wit migrate; see Syntax.
Runtime codes — RuntimeError
Thrown during resolve, expand or the load pass:
E_UNRESOLVED_REFERENCE— resolve:@namenames no definition, data, or core node. Define it, or fix the name.E_CIRCULAR_REFERENCE— resolve:referencefiles form a cycle. Break the cycle.E_MISSING_REFERENCE_FILE— resolve: areferencedirective but norootPath, or the file is missing. PassrootPath, or handle it withonMissingReference.E_DUPLICATE_DEFINITION— resolve: two non-additive#namedefinitions. Rename one, or make it a+#nameentry.E_PARTIAL_SHAPE_MISMATCH— resolve:+#nameentries disagree with each other or the base on shape or parameters.E_POSITIONAL_WITHOUT_HEADER— expand:@c(1952)for a definition with no header. Pass by name, or declare#c(year).E_TOO_MANY_ARGUMENTS— expand: more positional values than header parameters — often a value with a comma. Pass it by name.E_UNKNOWN_PARAM— expand: a leadingkey:the definition doesn't declare.E_MISSING_PARAM— expand: a use with parameters omits a declared one.E_REMOVED_SYNTAX— expand: a parameter written without its colon, the removed 0.2 form. Writeyear: 1952.E_AMBIGUOUS_RECORD_KEY— expand: two keys of one record match the same loose key (years at postandyears_at_post). Rename one.E_NOT_ITERABLE— expand:(each)targets a non-collection. Point it at a collection.E_EXPANSION_DEPTH_LIMIT— expand: a recursive definition past depth 256. Remove the recursion.E_SCRIPT_ERROR— expand: a<% %>block threw, or@scriptCallnamed an unknown function. Fix the script.E_LOAD_FAILED— load: a@loadalias's loader threw or the dict had no entry. Supply the data or fix the loader.E_MISSING_FIELD,E_TYPE_MISMATCH— declared inRuntimeErrorCodebut not thrown today; a missing field renders as a visiblewit-unresolvedspan instead.
How the CLI surfaces them
wit build formats both families identically through formatStageError:
report.wit:12:5: E_UNRESOLVED_REFERENCE: Unresolved reference @author
That is file:line:col: CODE: message — the same shape the embed helper produces.
See also
Parsing → the AST · Resolve & expand · External data · Scripting · CLI reference.