Skip to content

Compile-Error Catalogue

Every wick diagnostic has the form file:line: message and appears on the in-engine error screen. Fix the file and save; the game hot-reloads. The table below lists the compile-time messages by cause, with the meaning and the usual remedy. Message text in the reference compiler may vary in minor wording; the patterns here are canonical.

Message pattern Meaning and fix
expected str, got str? (any types) An optional (or a wrong type) used where a plain value is needed. Unwrap with ?? or narrow with if x != nil { }.
if condition must be bool (wick has no truthiness) if x on a number or string. Write the comparison: if x > 0, if s != "".
while condition must be bool As above, for while.
unknown variable ’x’ --- wick has no implicit globals; use let Assigned a name never declared (often a typo). Add let, or fix the spelling.
unknown variable ’x’ (declare it with let) Read of an undeclared name. Declare it, or fix the spelling.
’+’ needs num+num or str+str (use str(x)) Mixed-type +. Convert explicitly: "n=" + str(n).
’-’ needs num operands / arithmetic needs num operands An arithmetic operator with a non-num operand.
f() argument 3: expected num, got str A typed call mismatch (engine or your own function). Check the signature.
f() needs at least N arguments / takes N arguments Arity mismatch. See the signature.
unknown function ’f’ (wick requires declare-before-use) Called above its definition. Move the fn up.
can’t infer a type from nil; annotate: let x: str? = nil A bare nil initialiser. Add the annotation.
empty [] needs a type: let xs: list<num> = [] An untyped empty literal. Annotate the let.
list elements must share one type A heterogeneous literal such as [1, "a"]. Lists are homogeneous.
list elements must be num, bool, or str A container element of a disallowed type.
comparing non-optional to nil x != nil on a plain type; it can never be nil. Delete the check.
’??’ left side must be an optional a ?? b where a can never be nil. Delete the ??.
’??’ default must be T The default’s type does not match the optional’s base type.
’x’ already declared in this scope / ’x’ already declared A duplicate let. Assign instead, or rename.
parenthesize this condition: (a != b) and ... A narrowing pattern mixed with and/or. Add parentheses.
break outside a loop / continue outside a loop A loop-control statement with no enclosing loop.
fn declarations can’t nest An fn inside another fn. Top level only (v0.3).
return outside a function A return at top level.
void function can’t return a value return expr in a function with no declared return type.
this function must return T A bare return, or a type mismatch, in a value-returning function.
map keys must be str literals Computed keys in a map literal. Build with m[k] = v.
container elements must be num, bool, or str A nested container. Flatten it (Chapter 5).
only lists and maps can be indexed Indexing a value that is not a list or map.
’and’/’or’ needs bool operands A logical operator with a non-bool operand.
unexpected character ’x’ A byte the lexer does not recognise.

Runtime errors

Static typing removes the compile-time classes above but cannot remove the following, which depend on values only known at run time. Each stops the frame and shows on the error screen with a line number.

Message Cause
list index N out of range (len M) An out-of-bounds xs[i], read or write.
check failed: <msg> Your own check() assertion failed.
load_texture/mesh/sound failed: <path> A missing or malformed asset.