Error Index

Every diagnostic code Notch reports, with a cause and a fix

Every Notch diagnostic carries a code in its header line:

 ERROR[EP0018]: 'break' outside a loop
   --> example.notch:1:1
    |
  1 | break
    | ^^^^^

Codes are stable. Once published a code is never renumbered and never reused, so it is safe to link to, search for, or match on in tooling.

Parser errors use EP codes. Tokenizer (ET) and runtime (EE) codes are being added. Extensions namespace their own as extension-name:E0001.

For the language features behind these errors - throw, try, catch - see Errors & Exceptions.

EP0001: expected condition after 'if' operator

The trailing if operator selects between values, so it needs a condition to test. Notch reports this when the line ends before one appears.

x = 1 if

Supply the condition after if, and a value after else, as in x = 1 if ready else 0.

EP0002: expected value after 'else' in 'if' expression

The trailing if operator always produces a value, so both branches must be present. The condition was read but nothing followed else.

x = 1 if true else

Give else a value, as in x = 1 if true else 0. Unlike the if statement, the if operator cannot leave a branch empty.

EP0003: expected expression after an operator

A binary operator needs a value on both sides. The left side and the operator were read, then the input ended or an unusable token followed. The message names the operator involved.

x = 1 +

Complete the right side of the operator, or remove the operator if it was a typo.

EP0004: 'catch' is not allowed in a recover expression

recover produces a replacement value when an expression fails. It is an expression-level construct, so it has no body in which statements could run, and catch therefore has nothing to attach to.

x = foo() catch 1

Use recover to substitute a value - x = foo() recover with 1 - or a block try / catch when you need statements to run on failure.

EP0005: expected expression after recover type

A typed recover names the failure it handles and then the value to use instead. The type was read but no replacement value followed.

x = foo() recover from RuntimeException

Add the replacement value after the type, as in x = foo() recover from RuntimeException 0.

EP0006: unexpected token after recover: expected 'recover' or end of line

A recover clause is complete, but more input followed on the same line that is not another recover. Recover clauses chain only with recover.

x = foo() recover from A 1 bogus

End the line after the recovery value, or start the next clause with recover.

EP0007: expected ',' between arguments

Call arguments are comma separated. One argument was read and another began without a separator between them.

foo(1 2)

Put a comma between the arguments, as in foo(1, 2).

EP0008: expected ')' to close the argument list

An argument list was opened but never closed - the input ended, or a token appeared that cannot continue the list.

foo(

Add the closing parenthesis. If the call spans lines, check that no earlier argument is missing its comma.

EP0009: expected a closing parenthesis

A parenthesised group was opened but never closed. If the offending token is =, Notch adds a note - a common cause is writing assignment where a comparison was meant.

(1 + 2

Add the closing parenthesis. If you meant to compare two values, use ==; = assigns.

EP0010: a keyword cannot be used as a property name

Notch keywords are reserved everywhere, including after a dot, so a member whose name collides with one cannot be reached with member-access syntax. The message names the keyword involved.

x.throw

Rename the member if it is yours. A JVM member whose name collides with a Notch keyword - System.out.print, for instance - is currently unreachable through member access; there is no workaround short of wrapping it in Java.

EP0011: expected a statement

The parser found a token that can neither begin a statement nor continue the previous one. This is the general fallback when nothing more specific fits, and often follows recovery from an earlier error.

end

Check for a stray token, an unbalanced end, or a construct that was left incomplete on an earlier line.

EP0012: cannot assign to this expression

The left side of an assignment must name a place a value can be stored - a variable, a property, or an indexed element. A computed expression is not one.

x + 1 = 5

Assign to a variable, property, or index. If you meant to compare, use ==.

EP0013: this expression cannot be used as a statement

A statement must do something: call a function or method, or assign. An expression that only produces a value and discards it is reported here.

foo
bar = 5

Assign the value to a variable, pass it somewhere, or return it if you are inside a function or closure.

EP0014: expected an expression after 'throw' on the same line

throw needs the value to raise, and it must appear on the same line. A value on the next line is a separate statement.

throw

Put the value on the same line, as in throw 'boom' or throw RuntimeException('boom').

EP0015: 'rethrow' outside a catch

rethrow re-raises the exception a catch is currently handling, so it is only meaningful inside one.

rethrow

Move the rethrow inside a catch body, or use throw with an explicit value.

EP0016: catch body must start on a new line

The catch clause header - the type, and an optional as binding - occupies its own line. The body begins on the line after.

try
  print(1)
catch RuntimeException print(2)
end

Move the body to the next line. To bind the exception, finish the header with as, as in catch RuntimeException as e.

EP0017: expected 'times' after count expression in 'repeat'

The counted form of repeat reads repeat <count> times. The count was read but the times keyword did not follow.

repeat 3
end

Add times after the count - repeat 3 times - or use repeat while <cond> for a conditional loop.

EP0018: 'break' / 'continue' outside a loop

break and continue only mean something inside a loop body. Notch reports this when one appears at the top level, inside a function body, or inside a closure that is not itself within a loop.

print('start')
break

Move the statement inside a loop body, or remove it. Note that a closure defined inside a loop still cannot break the enclosing loop - the closure is its own body, and the loop has already moved on by the time it runs.

EP0019: 'return' outside a function

return hands a value back to a caller, so it needs a function or closure to return from. At the top level there is no caller.

return 1

Move the return inside a function or a closure body. At the top level, assign the value or print it instead.

EP0020: expected a 'field' or 'function' declaration in the class body

A class body holds only field and method declarations. Statements do not run directly in it, so anything that is not a field or function is reported here.

class P
  x = 1
end

Declare the member with field x, and set its value in a method. Move any executable code into a function.

EP0021: cannot assign to 'this'

this is bound by the runtime to the object whose method is executing. It is not a variable, so it cannot be reassigned.

class P
  function f()
    this = 1
  end
end

Assign to a field on the object instead, as in this.x = 1.

EP0022: a keyword cannot be used as a loop variable name

The loop variable in a for is a new name bound on each iteration, so it must be an identifier. Keywords are reserved and cannot be rebound.

for print in [1]
end

Choose a name that is not a keyword, such as item or value.

EP0023: expected a conditional expression after 'if'

An if statement tests a condition, which must follow the if on the same line. Nothing usable was found.

if
end

Supply the condition, as in if x > 0. For the value-selecting form, see EP0001.

EP0024: expected '(' after 'print'

print is a keyword and its arguments are always parenthesised. When an argument follows on the same line without parentheses, Notch adds a note showing the intended form.

print hello

Wrap the arguments in parentheses, as in print(hello).

EP0025: expected ')' to close the print arguments

The argument list for print was opened but never closed.

print(1

Add the closing parenthesis.

EP0026: a declaration keyword from another language is not valid here

Notch has no var, let, const, or type-name declaration syntax. A variable comes into existence when you assign to it. The message names the word that was used.

var hello = 1

Drop the keyword and assign directly, as in hello = 1.

EP0027: expected an expression after 'recover'

An untyped recover handles any failure, so recover with must be followed by the value to use when the guarded expression fails. Nothing followed it here. This is the untyped counterpart of EP0005: no exception type was named, so the parser was waiting on the replacement value alone.

x = foo() recover with

Add the replacement value after with, as in x = foo() recover with 0. To handle one specific failure instead, name the type: recover from IOException with 0, which reports EP0005 when its value is missing.

EP0028: expected an index expression

Indexing with [ and ] needs a value between the brackets saying which element to reach. The brackets were found empty. Notch has no "whole slice" meaning for [].

arr[] = 5

Put the index between the brackets, as in arr[0] = 5. To append to a list, use its add method rather than an empty index.

EP0029: expected an expression to throw

throw needs a value naming what to raise, and it must start on the same line as the keyword. Something followed throw on that line, but it could not begin an expression.

throw )

Give throw an exception value, as in throw RuntimeException("boom"). If the line after throw is empty instead, that is EP0014.

EP0030: expected a condition after a repeat guard

repeat while and repeat until both test a condition before each pass, so one has to follow the guard keyword. The message names which of the two was used.

repeat while
end

Supply the condition, as in repeat while x < 10. For a loop that runs a fixed number of times, use repeat n times instead.

EP0031: expected a count expression after 'repeat'

A bare repeat starts a counted loop, so it needs an expression saying how many passes to make, followed by times. The loop body began before one appeared.

repeat
end

Give the count and keep times, as in repeat 3 times. For a condition-driven loop, write repeat while ... or repeat until ... instead.

EP0032: expected an initializer expression after '='

A field declaration may give a default value with =, but the value itself was missing. This is the class-body form; an ordinary assignment reports EP0033.

class Foo()
  field x =
end

Give the field its default, as in field x = 0, or drop the = to leave the field uninitialized.

EP0033: expected an expression after '='

An assignment needs a value on the right of =. The target and the = were read, then the line ended. This is the statement form; a class field default reports EP0032.

x =

Supply the value, as in x = 1.

EP0034: expected an expression for the loop iterable

A for loop walks a collection, so in must be followed by the thing to walk. The loop body began before one appeared.

for x in
end

Give the loop something to iterate, as in for x in [1, 2, 3]. Any list, set, or map works.

EP0035: expected a property name

A . reaches into an object, so it must be followed by the name of the property or method to reach. The dot was read but no name followed.

x = a.

Name the property after the dot, as in x = a.size. A dot cannot end a line.

EP0036: expected a class name after 'new'

new constructs an instance, so it needs the name of the class to build. Nothing usable followed the keyword.

x = new

Name the class and give it an argument list, as in x = new Dog("Rex").

EP0037: expected an alias after 'as'

In an import, as renames what was imported, so a name must follow it. The line ended first.

import java.util.List as

Give the alias, as in import java.util.List as JList, or drop the as clause to keep the original name.

EP0038: expected a binding name after 'as'

In a catch clause, as binds the caught exception to a variable, so it needs a name. Nothing followed it.

try
  print(1)
catch IOException as
end

Name the variable, as in catch IOException as e, or drop the as clause if the exception value is not needed.

EP0039: expected a parameter name

Parameters are declared by name. Something that is not an identifier appeared where a parameter name belongs - in a function declaration or a closure's parameter list.

function foo(1)
end

Use an identifier for each parameter, as in function foo(count). Literals and keywords cannot be parameter names.

EP0040: expected a function name

A function declaration names the function before its parameter list. The function keyword was read but no name followed. If a ( followed directly, the error adds a note - Notch functions are always named, and an anonymous function is written as a closure instead.

function 1()
end

Give the function a name, as in function greet(). For an anonymous function, use a closure: \ x -> x + 1.

EP0041: expected a class name

A class declaration names the class before its header. The class keyword was read but no name followed.

class 1
end

Give the class a name, as in class Dog.

EP0042: expected a field name

A field declaration names the field after the field keyword. Something that is not an identifier appeared instead.

class Foo
  field 1
end

Name the field, as in field age, optionally with a type and default: field age: Int = 0.

EP0043: expected a variable name for the loop item

A for loop binds each element to a variable, so a name must follow for. Something that is not an identifier appeared instead.

for 1 in [1]
end

Name the loop variable, as in for item in [1, 2, 3].

EP0044: expected a variable name for the loop index

The optional index clause of a for loop binds the position of each element to a variable, so it needs a name.

for x in [1] index 1
end

Name the index variable, as in for x in [1, 2] index i, or drop the index clause.

EP0045: expected 'with' after a string comparison keyword

The starts and ends operators are spelled as two words. The first word was read but with did not follow. The message names which one was used.

x = "a" starts 1

Add with, as in x = "abc" starts with "a" or x = "abc" ends with "c".

EP0046: expected 'end' to close a block

Every block form in Notch - try, repeat, function, class, for and the if statement - runs until a matching end. The input finished while one was still open. The message names which construct, and try and if add a note about their own shape.

if true
  print(1)

Add end on its own line to close the block. For try, any catch clauses go before the end; the trailing if operator (x = 1 if ready else 0) is an expression and needs no end at all.

EP0047: expected 'in' after the loop variable

A for loop is written for <name> in <collection>. The loop variable was read but in did not follow.

for x [1]
end

Add in between the variable and the collection, as in for x in [1, 2, 3].

EP0048: expected a type name after 'import'

An import names a Java type to bring into scope. The import keyword was read but no name followed.

import

Name the type, as in import java.util.List. Notch reaches Java only through explicit imports or fully qualified names.

EP0049: expected a type after ':'

A : introduces a type annotation - on a parameter, on a function's return, or on a field - so a type name must follow it. The colon was read but nothing usable came next. The message names which of the three positions it was.

function foo(x: )
end

Name the type, as in function foo(x: Int): Int or field age: Int, or drop the : to leave it untyped. A : introduces a type, never a value.

EP0050: expected ']' to close the index expression

An index expression opens with [ and must close with ]. The index was read but the closing bracket never appeared.

x = arr[1

Add the closing bracket, as in x = arr[1].

EP0051: expected '(' after the class name

new requires an argument list even when the constructor takes nothing. The class name was read but no ( followed.

x = new Foo

Add the argument list, as in x = new Foo().

EP0052: expected ',' between list elements

Elements of a list literal are separated by commas. Two elements appeared with nothing between them.

x = [1 2]

Separate the elements, as in x = [1, 2].

EP0053: expected ']' to close the list

A list literal opens with [ and must close with ]. The input finished while the list was still open.

x = [

Add the closing bracket, as in x = [1, 2] or x = [] for an empty list.

EP0054: expected '}' to close a brace literal

Sets and maps are written with braces and must be closed. The input finished while one was still open. The message names which - map, set, or the empty set - and the empty-set case adds a note, because {,} and {} mean different things.

x = {1 -> 2

Add the closing brace, as in x = {1 -> 2} for a map or x = {1, 2} for a set. The empty set is {,}; {} on its own is the empty map.

EP0055: expected '->' between a map key and value

Map entries are written key -> value. A key was read but no arrow followed, so the literal could not be read as a map.

x = {1 -> 2, 3}

Give every entry an arrow, as in x = {1 -> 2, 3 -> 4}. For a set, drop the arrows entirely: x = {1, 2}.

EP0056: expected ',' between parameters

Parameters are separated by commas, in both function declarations and closure parameter lists. Two parameters appeared with nothing between them.

function foo(a b)
end

Separate the parameters, as in function foo(a, b).

EP0057: expected '->' after the closure parameters

A closure is written \ params -> body. The parameter list was read but the arrow never appeared.

x = \

Add the arrow, as in x = \ a -> a + 1. A closure with no parameters is written \ -> ....

EP0058: expected '}' to close the closure body

A block-bodied closure opens with { and must close with }. The input finished while the body was still open.

x = \ -> { print(1)

Add the closing brace, as in x = \ -> { print(1) }. For a single expression, drop the braces: x = \ -> 1.

EP0059: expected '(' after the function name

A function declaration always has a parameter list, even when empty. The name was read but no ( followed.

function foo
end

Add the parameter list, as in function foo().

EP0060: expected ')' to close a declaration list

A function's parameter list and a class header's field list both open with ( and must close with ). The input finished while one was still open; the message names which.

function foo(

Add the closing parenthesis, as in function foo(a, b) or class Foo(name).

EP0061: 'catch' without a matching 'try'

A catch clause is part of a try statement - it is read as part of the try that precedes it. Reaching catch on its own means no open try block was found, usually because the try is missing or was already closed by an end.

catch e

Put the catch after a try body and before its end, as in try / risky() / catch IOException as e / print(e) / end. Check that an earlier end did not close the try too soon.

EP0062: 'else' without a matching 'if'

An else branch belongs to an if statement and is read as part of it. Reaching else on its own means no open if was found, usually because the if is missing or was already closed by an end.

else

Put the else inside an if statement, before its end, as in if ready / go() / else / wait() / end. Note the trailing if operator (x = 1 if ready else 0) is an expression and needs no end.