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,.code: ErrorCodeName, 12 codes. Thrown byparse. - Runtime —
RuntimeError(base), with subclassesResolverError(resolve) andExpanderError(expand),.code: RuntimeErrorCodeName, 14 codes.
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 node opened but never closed (@aside oops). Fix: add the closingaside@.E_UNCLOSED_COMMENT— a block comment left open. Close it.E_UNCLOSED_DEFINITION— a#nameblock without itsname#. Close the definition.E_UNCLOSED_PAREN— a@x(param list with no). Balance the parens.E_MISMATCHED_CLOSE— a close tag names the wrong node (@a … b@). Match the opener's name.E_MALFORMED_RECORD— a{ … }record with a field missing its key or separator. Usekey - valueorkey: value.E_UNCLOSED_COLLECTION— a[ …collection with no closing]. Close it.E_UNCLOSED_SCRIPT— a<%with no%>. Close the script.E_UNCLOSED_RAW_NODE— a@@nameraw node left open. Addname@@.E_MIXED_PARAM_SOURCE— parens and pipes mixed illegally on one call. Pick one param form.E_MALFORMED_FORM_FIELD— a form-fill body line that isn'tkey: value. Fix the field.E_UNTERMINATED_STRING— a quoted value with no closing quote. Close the quote.
Runtime codes — RuntimeError
Thrown during resolve or expand (and load):
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+#namepartial.E_PARTIAL_SHAPE_MISMATCH— resolve: a+#namepartial's shape disagrees with its base. Match the base shape.E_MISSING_FIELD— expand: an access path reaches a field that doesn't exist. Fix the path or the data.E_MISSING_RECORD_FIELD/E_EXTRA_RECORD_FIELD— expand: record arguments don't match the expected fields. Align them.E_AMBIGUOUS_RECORD_KEY— expand: a key resolves to more than one field. Disambiguate the key.E_TYPE_MISMATCH— expand: a value used where another type was required. Fix the type.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.
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 :col: CODE: message — the same shape the embed helper produces.
See also
Parsing → the AST· Resolve & expand · External data · Scripting · CLI reference.