Skip to content

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.

output x = If(true, then: 1, 2)
  • errorsyntax_errorPositional argument after a named argument

unexpected_tokenerror

Something turned up where no expression could begin.

output x = )
  • errorunexpected_tokenUnexpected ')'

unexpected_enderror

The program ran out mid-expression: a bracket or an argument list was left open.

output x = [1, 2
  • errorunexpected_endExpected ] but found 'eof'

duplicate_bindingerror

Two bindings share a name. The first one is kept.

let x = 1
let x = 2
output y = x
  • errorduplicate_bindingDuplicate binding 'x'

unterminated_stringerror

A string literal has no closing quote, or a template no closing backtick (a hole left open counts too).

output x = "abc
  • errorunterminated_stringUnterminated string literal

unknown_charactererror

A character that is neither part of the language nor claimed by any operator.

output x = @
  • errorunknown_characterUnexpected character '@'
  • errorunexpected_endUnexpected 'eof'

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.

output x = 1 /* runs off
  • warningunterminated_commentUnterminated block comment
  • warningunknown_program_outputOutput 'x' is not declared in the descriptor

invalid_escapewarning

A backslash escape the lexer does not know. Both characters are kept as written.

output x = "a\qb"
  • warninginvalid_escapeUnknown escape sequence '\q'
  • warningunknown_program_outputOutput 'x' is not declared in the descriptor

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'2bad' is not a valid input 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_nameinput 'a' is declared twice in layer 'doc'

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_nametype 'number' in layer 'doc' is already declared by the language

unknown_port_typeerror

A declaration names a type nothing registered.

Raised while these compose, whatever the program says.

declared inputs
$a: Nope
  • errorunknown_port_typeType 'Nope' is referenced by input 'a' but is not registered

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_overrideField 'id' of 'Child' has type 'string', incompatible with 'number' inherited from 'Parent'

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.

if the syntax allowed it
output x = Nope(1)
xany
—
as a host builds it
bindings: {},
outputs: { x: operationNode("Nope", { a: { kind: "literal", value: 1 } }) },
  • errorunknown_opOp 'Nope' is not registered in the descriptor

unknown_program_inputerror

The program reads a `$name` that nothing declared.

output x = $nope
xany
—
  • errorunknown_program_inputContext input 'nope' is not declared in the descriptor

unknown_typeerror

A type written in the program is one the language does not have.

let rows: nubmer[] = [1, 2]
output x = Average(rows)
  • errorunknown_typeType 'nubmer' is not registered
  • warningunknown_program_outputOutput 'x' is not in the descriptor and depends on a failed binding

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.

let a = b
let b = a
output x = a
xany
—
  • errorbinding_cycle'a' is part of a reference cycle
  • errorbinding_cycle'b' is part of a reference cycle
  • erroroutput_depends_on_failed_bindingOutput 'x' depends on a binding that failed analysis

undeclared_binding_referenceerror

A name that is not a binding, an input, or a lambda parameter.

output x = nope
xany
—
  • errorundeclared_binding_reference'nope' is not declared as a binding or scoped variable

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.

let early = late
let late  = 1
output x  = early
xany
—
  • errorforward_reference'late' is referenced before it is declared (declared at line 2)
  • erroroutput_depends_on_failed_bindingOutput 'x' depends on a binding that failed analysis

unknown_fielderror

Field access on a struct type that has no such field.

declared types
Bus { id: number }
$busBus
output x = $bus.nope
xany
—
  • errorunknown_fieldType 'Bus' has no field 'nope'

op_input_type_mismatcherror

An op input was handed a value of a type it does not accept.

output x = And(true, "Country")
xany
—
  • errorop_input_type_mismatchInput 'nodes' of 'And' has type 'string', which is not compatible with expected 'boolean'

program_output_type_mismatcherror

An output produces a value that does not fit the type it was declared with.

output out = "text"
outnumber
—
  • errorprogram_output_type_mismatchOutput 'out' type 'string' is not compatible with expected 'number'

output_depends_on_failed_bindingerror

The output was dropped because something it reads failed. Only this output is lost; the others still run.

let bad  = And(true, "Country")
output x = bad
xany
—
  • errorop_input_type_mismatchInput 'nodes' of 'And' has type 'string', which is not compatible with expected 'boolean'
  • erroroutput_depends_on_failed_bindingOutput 'x' depends on a binding that failed analysis

binding_type_mismatcherror

A binding states a type its value does not have.

let n: number = "a"
output x = n
  • errorbinding_type_mismatchBinding 'n' has type 'string', which is not compatible with expected 'number'
  • warningunknown_program_outputOutput 'x' is not in the descriptor and depends on a failed binding

cast_to_functionerror

A cast to a function type. A function value cannot be checked at runtime, so the cast could never succeed.

let f = (n: number) => n
output x = f as (number) -> boolean
  • errorcast_to_functionCannot cast to '(number) -> boolean': a function value cannot be checked at runtime

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.

if the syntax allowed it
let f = (n: number): string => n
output x = f(1)
xany
—
as a host builds it
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_mismatchThe lambda's return has type 'number', which is not compatible with expected 'string'
  • erroroutput_depends_on_failed_bindingOutput 'x' depends on a binding that failed analysis

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).

let label = (n~) => n
output x = label(1)
xany
—
  • errorinvalid_convert_paramParameter 'n' is marked '~' but states no type to convert to: write (n~: string)
  • erroroutput_depends_on_failed_bindingOutput 'x' depends on a binding that failed analysis

app_callee_not_functionerror

Something that is not a function was called.

let n = 1
output x = n(1)
xany
—
  • errorapp_callee_not_functionApplication callee has type 'number', which is not a function

app_argument_mismatcherror

The arguments do not line up with the function's parameters.

let f = x => x
output y = f(1, 2)
yany
—
  • errorapp_argument_mismatchToo many positional arguments: 2 for 1 parameter(s)

app_argument_type_mismatcherror

An argument's type does not fit the parameter it resolved to.

let f = (x: number) => x
output y = f("text")
yany
—
  • errorapp_argument_type_mismatchArgument 'x' has type 'string', which is not compatible with expected 'number'

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.

output other = 1
needednumberrequired
—
othernumber
—
  • errormissing_required_program_outputRequired output 'needed' is not declared in the program

unknown_program_outputwarning

The program declares an output nobody asked for. It is dropped.

output nobodyWants = 1

Its layer declares no inputs and no outputs.

  • warningunknown_program_outputOutput 'nobodyWants' is not declared in the descriptor

unused_bindingwarning

A binding no output can reach. It is dropped from the program that runs.

let spare = 1
output x = 2
xany
2
  • warningunused_bindingBinding 'spare' is declared but never referenced by any output

missing_desired_program_outputwarning

An output the host would have liked is not declared.

output other = 1
wantednumberdesired
—
othernumber
1
  • warningmissing_desired_program_outputDesired output 'wanted' is not declared in the program

field_access_on_primitivewarning

Field access on a number, string or boolean, which has no fields.

$nnumber
output x = $n.field
xany
—
  • warningfield_access_on_primitiveField access 'field' on primitive type 'number'

unknown_op_input_keywarning

An argument named for an input the op does not have. It is ignored.

output x = If(condition: true, then: 1, else: 2, nope: 3)
xany
1
  • warningunknown_op_input_keyInput key 'nope' is not declared by op 'If'

missing_op_inputwarning

An op input was left out; the type's default stands in. This is why a half-written program keeps running.

output x = If(true, 1)
xany
1
  • warningmissing_op_inputRequired input 'else' of op 'If' is absent - using type default

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.

output x = "five" as number
  • warningcast_never_fitsThe value is 'string' typed and can never fit 'number': this cast is always null
  • warningunknown_program_outputOutput 'x' is not declared in the descriptor

implicit_any_castwarning

An `any` value flowed somewhere narrower. Allowed, and the reason it might fail at runtime instead.

$looseany
output x = Add($loose, 1)
xnumber
1
  • warningimplicit_any_cast'$loose' is 'any' typed - 'number' expected

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.