Every diagnostic
Every kind of error and warning the language can produce, grouped by the stage you meet it at. Each one says what it means and, where a program can provoke it, shows one that does, with the inputs, outputs and types that program was checked against.
Not everything is provoked by a program. The Compose kinds are raised while those declarations compose, before a program is read, so those entries show the declarations alone. Two kinds cannot be written as text at all (they show the host code that builds the node instead), and the Evaluate kinds happen while a compiled program runs, so each of those says what brings it about. The Input kind is about a value a host pushes, not about the program, and says the same.
None of this page is written by hand. It is printed from the language’s own registry, a new kind does not compile until it is documented there, and a test runs every sample below on every build. If an entry disagrees with what you are seeing, the entry is what is wrong, and it is a bug.
Two severities, and they mean different things. An error stops the output that depends on it, and the rest of the program still runs. A warning changes nothing: it tells you that something is pointless, lossy, or not what you probably meant.
Load
The stored program itself, before a character of it is read.
unsupported_formerror
The saved program is in a form this build cannot read.
What triggers it: Loading a `rete`-form program: the graph adapter does not exist yet.
unsupported_versionerror
The saved program was written by a newer version of the format.
What triggers it: Loading a blob whose `version` is higher than this build's.
malformed_programerror
The stored blob is not a program: its shape, or its ports, did not survive.
What triggers it: Loading hand-edited or truncated JSON: an `ast` form with a node kind that does not exist, or a `ports` key that is not ports.
Parse
The text: what the lexer and the parser make of it.
syntax_errorerror
The text is not a program at this point.
- errorsyntax_error
unexpected_tokenerror
Something turned up where no expression could begin.
- errorunexpected_token
unexpected_enderror
The program ran out mid-expression: a bracket or an argument list was left open.
- errorunexpected_end
duplicate_bindingerror
Two bindings share a name. The first one is kept.
- errorduplicate_binding
unterminated_stringerror
A string literal has no closing quote, or a template no closing backtick (a hole left open counts too).
- errorunterminated_string
unknown_charactererror
A character that is neither part of the language nor claimed by any operator.
- errorunknown_character
- errorunexpected_end
deprecated_syntaxwarning
A form that still parses but has been replaced.
What triggers it: Nothing today. The kind is reserved: no form has been deprecated yet, so nothing in the language emits it.
unterminated_commentwarning
A block comment runs to the end of the file. It is still read as a comment.
- warningunterminated_comment
- warningunknown_program_output
Compose
Composing the declarations a program is checked against. These name a layer and a declaration rather than a line.
invalid_nameerror
A declared name is not a legal identifier.
Raised while these compose, whatever the program says.
- declared inputs
- $2bad: number
- errorinvalid_name
duplicate_nameerror
One layer declares the same name twice.
Raised while these compose, whatever the program says.
- declared inputs
- $a: number$a: number
- errorduplicate_name
shadowed_nameerror
A layer claims a name an earlier layer, or the language, already has. Order is authority: the later one is the problem.
Raised while these compose, whatever the program says.
- declared types
- number
- errorshadowed_name
unknown_port_typeerror
A declaration names a type nothing registered.
Raised while these compose, whatever the program says.
- declared inputs
- $a: Nope
- errorunknown_port_type
incompatible_field_overrideerror
A struct field's type clashes with the one it inherits from the type it extends.
Raised while these compose, whatever the program says.
- declared types
- Parent { id: number }Child extends Parent { id: string }
- errorincompatible_field_override
missing_evaluatorerror
An op was registered with no evaluator, so nothing could ever run it.
Raised while these compose, whatever the program says.
What triggers it: A language that calls `registerOp` without a matching `registerEvaluator`. It is a mistake in the language, not in a program, so composing THROWS rather than reporting: the editor shows it as a failed mount.
orphan_evaluatorerror
An evaluator was registered for an op that does not exist, usually a typo.
Raised while these compose, whatever the program says.
What triggers it: A `registerEvaluator` whose `op` name matches nothing. Like a missing evaluator, this throws when the language composes.
invalid_convert_inputerror
An op input is declared `convert: true` but cannot carry it.
Raised while these compose, whatever the program says.
What triggers it: A `registerOp` input with `convert` on a struct, a function or `any` (no conversion rule exists), on a variadic input, or on an optional one (an absent value would arrive converted rather than absent). Like a missing evaluator, this throws when the language composes.
Analyse
The program against those declarations. Almost everything lives here.
unknown_operror
A call names an op the language does not have.
Not writable as text: As text, `Nope(1)` is a call on an unknown NAME (an undeclared_binding_reference), because only a node built without the parser names an op. This one needs a stored `ast` program, or a host operator that desugars to an op nobody registered.
output x = Nope(1)any—bindings: {},
outputs: { x: operationNode("Nope", { a: { kind: "literal", value: 1 } }) },- errorunknown_op
unknown_program_inputerror
The program reads a `$name` that nothing declared.
- errorunknown_program_input
unknown_typeerror
A type written in the program is one the language does not have.
- errorunknown_type
- warningunknown_program_output
binding_cycleerror
Bindings depend on each other in a loop, so none of them has a value. This is also why a name cannot refer to itself, and why every program finishes.
- errorbinding_cycle
- errorbinding_cycle
- erroroutput_depends_on_failed_binding
undeclared_binding_referenceerror
A name that is not a binding, an input, or a lambda parameter.
- errorundeclared_binding_reference
forward_referenceerror
In code, a name is used above the line that declares it. A rule about the text, not the language: the same program built as a graph carries no such rule.
- errorforward_reference
- erroroutput_depends_on_failed_binding
unknown_fielderror
Field access on a struct type that has no such field.
- declared types
- Bus { id: number }
- errorunknown_field
op_input_type_mismatcherror
An op input was handed a value of a type it does not accept.
- errorop_input_type_mismatch
program_output_type_mismatcherror
An output produces a value that does not fit the type it was declared with.
- errorprogram_output_type_mismatch
output_depends_on_failed_bindingerror
The output was dropped because something it reads failed. Only this output is lost; the others still run.
- errorop_input_type_mismatch
- erroroutput_depends_on_failed_binding
binding_type_mismatcherror
A binding states a type its value does not have.
- errorbinding_type_mismatch
- warningunknown_program_output
cast_to_functionerror
A cast to a function type. A function value cannot be checked at runtime, so the cast could never succeed.
- errorcast_to_function
lambda_return_type_mismatcherror
A lambda's body does not produce what its return annotation promised.
Not writable as text: The syntax annotates a parameter but not a return, so only a stored `ast` program carries one. Written as text, handing a lambda to an op that wanted another shape is an op_input_type_mismatch on that op's input instead.
let f = (n: number): string => n
output x = f(1)any—bindings: {
f: {
kind: "lambda",
params: [{ name: "n", type: Type.number }],
returnType: Type.string,
body: { kind: "ref", name: "n" },
},
},
outputs: {
x: {
kind: "app",
callee: { kind: "ref", name: "f" },
positional: [{ kind: "literal", value: 1 }],
named: {},
},
},- errorlambda_return_type_mismatch
- erroroutput_depends_on_failed_binding
invalid_convert_paramerror
A lambda parameter is marked `~` but has nothing to convert to: it states no type, or a type with no conversion (only string, number, boolean or a list of them has one).
- errorinvalid_convert_param
- erroroutput_depends_on_failed_binding
app_callee_not_functionerror
Something that is not a function was called.
- errorapp_callee_not_function
app_argument_mismatcherror
The arguments do not line up with the function's parameters.
- errorapp_argument_mismatch
app_argument_type_mismatcherror
An argument's type does not fit the parameter it resolved to.
- errorapp_argument_type_mismatch
missing_required_program_outputerror
An output the host marked required is missing, or was dropped. This is the one case that fails the whole program.
- errormissing_required_program_output
unknown_program_outputwarning
The program declares an output nobody asked for. It is dropped.
Its layer declares no inputs and no outputs.
- warningunknown_program_output
unused_bindingwarning
A binding no output can reach. It is dropped from the program that runs.
- warningunused_binding
missing_desired_program_outputwarning
An output the host would have liked is not declared.
- warningmissing_desired_program_output
field_access_on_primitivewarning
Field access on a number, string or boolean, which has no fields.
- warningfield_access_on_primitive
unknown_op_input_keywarning
An argument named for an input the op does not have. It is ignored.
- warningunknown_op_input_key
missing_op_inputwarning
An op input was left out; the type's default stands in. This is why a half-written program keeps running.
- warningmissing_op_input
cast_never_fitswarning
A cast between two types neither of which fits the other, so the result is always null. Allowed, because it is pointless rather than unsound.
- warningcast_never_fits
- warningunknown_program_output
Evaluate
While the program runs. These do not arrive as diagnostics: an evaluation failure reaches a host on the outputs instead.
input_not_seterror
An input had no value when something needed it.
What triggers it: Evaluating outside the runtime, with `run()` over a state whose `inputs` map lacks a name the program reads. Through a runtime or an instance every declared input is seeded first, so this one stays a safety net.
invalid_field_accesserror
A field was read from a value that does not have it.
What triggers it: A host pushing a value that does not match the struct type its input was declared with. Nothing validates a pushed value against its type yet. A field of `null` is not this: it reads as `null`.
host_errorerror
An op's own evaluator threw.
What triggers it: Any `registerEvaluator` function that raises: a host op reaching for something that is not there. The op's name and the original message come with it.
evaluator_not_founderror
A compiled node names an op with no evaluator.
What triggers it: Nothing a program can do: composing rejects a language whose ops lack evaluators, so this is a safety net for a descriptor swapped underneath a compiled program.
undefined_referenceerror
A reference survived analysis but names nothing at evaluation time.
What triggers it: An analyser bug, or a hand-built core program that was never analysed.
error_node_reachederror
A node that failed analysis was reached anyway.
What triggers it: An analyser bug: pruning should have dropped it with the output that read it.
not_a_functionerror
Something applied as a function did not evaluate to one.
What triggers it: An analyser bug: the checker rejects a call on anything that is not function-typed, so reaching this means a program ran unchecked.
Input
A value pushed into an input of a running program. An instance refuses one that does not fit the input's type and reports it here, marked refused. A runtime used on its own throws instead.
value_does_not_fiterror
A value pushed into an input does not fit the type the input declares. The push is refused and the input keeps its value.
What triggers it: A host, a pane or a replica calling `setInput` or `fireTrigger` on an instance with a value of another type: a string for a `number`, or a struct with a declared field missing. A runtime used directly throws instead.