Skip to content

Onion Compiler Error Codes

Onion reports compilation errors with stable codes. This page explains the most common codes and suggests how to fix them.

Internal errors

I0000 — Internal compiler error

An unexpected exception escaped from a compiler phase. This is a bug in the compiler, not in your program. Please reduce the source to a minimal reproducer and file an issue.

Type errors

E0000 — Incompatible type

A value of one type was used where a different type was expected.

val x: Int = "hello"   // E0000: String where Int expected

Common fixes: - Check the expected type and convert the value explicitly (e.g. Int::parseInt(s)). - For nullable-to-non-null mismatches, the compiler now appends a hint suggesting !!, ?:, or a null-check.

val name: String? = lookup()
val sure: String = name     // E0000 + nullable hint
val fixed: String = name ?: ""

E0001 — Incompatible operand type

An operator was applied to a type it does not support.

val b = true + 1   // E0001

E0066 — Raw generic type not allowed

A generic type was used without type arguments. Onion forbids raw generic types; supply the type arguments explicitly.

val xs: List = [1]        // E0066: raw List
val ok: List[Int] = [1]   // fixed

E0067 — Missing return

A value-returning method has a block body that can complete without returning a value. Return on every path, or use an expression body.

class C {
public:
  static def f(): Int { 5 + 10 }   // E0067: value is never returned
}

Fixes: - Add an explicit return: { return 5 + 10 }. - Use an expression body: def f(): Int = 5 + 10.

E0027 — Type is not boxable

A void-typed expression (the result of calling a void method) was used where a value is required, e.g. as an operand of string concatenation. void has no boxed form, so there is nothing to box.

class Test {
public:
  static def main(args: String[]): Int {
    val s = "a" + IO::println("b")   // E0027: IO::println returns void
    return 0
  }
}

Fix: don't use the result of a void call as a value — call it as its own statement instead.

E0028 — Lvalue required

The left-hand side of an assignment is not an assignable location (a local variable, field, or array element) — e.g. a method call result or a literal.

class Test {
public:
  static def main(args: String[]): Int {
    "a".length() = 3   // E0028: the left side isn't an assignable location
    return 0
  }
}

Fix: assign to a variable, field, or array element instead.

E0036 — Cannot assign to val

A val-declared binding — a local variable, or an instance field written from outside its constructor — was reassigned (or incremented/decremented) after its initial assignment.

class Test {
public:
  static def main(args: String[]): Int {
    val x: Int = 1
    x = 2   // E0036: x is a val, not a var
    return x
  }
}

Fix: declare the binding var if it needs to change, or assign an instance val field only once, from within the constructor.

E0030 — Type is not generic

Type arguments were supplied for a type that takes none.

class Test {
public:
  static def main(args: String[]): Int {
    val x: String[Int] = null   // E0030: String takes no type arguments
    return 0
  }
}

Fix: drop the type arguments (String, not String[Int]).

E0031 — Type argument arity mismatch

A generic type was applied with the wrong number of type arguments.

class Box[T] { public: def this {} }
class Test {
public:
  static def main(args: String[]): Int {
    val b = new Box[String, String]()   // E0031: Box takes 1, not 2
    return 0
  }
}

This also fires when the mismatch is written inside a nullable type annotation, e.g. val b: Box[String, String]? = null.

E0032 — Type argument must be a reference type

Guards against substituting void for a type parameter. The check has live report sites in the type checker, but is not reachable from valid Onion source today: the grammar's type() production, used at every type-argument and type-alias-target position, never routes through void_type() (only a method's return_type() does). So void/Unit cannot actually be written as a type argument — new Box[void](), Box[void], and type T = void are all syntax errors, not E0032. See SemanticErrorCodeCoverageSpec for the reasoning behind leaving this one untriggered rather than fabricating a non-existent example.

E0033 — Method is not generic

Type arguments were supplied at a call site for a method that takes none.

class Test {
public:
  static def main(args: String[]): Int { return "abc".length[String]() }   // E0033
}

Fix: drop the type arguments from the call ("abc".length()).

E0034 — Method type argument arity mismatch

A generic method call supplied the wrong number of explicit type arguments.

class Test {
public:
  static def main(args: String[]): Int {
    val l = java.util.Collections::emptyList[String, String]()   // E0034: expects 1, not 2
    return 0
  }
}

E0035 — Erased JVM signature collision

Two overloads have parameter types that differ in Onion's type system but erase to the same JVM method descriptor (generics are erasure-based, so List[String] and List[Integer] are indistinguishable at the bytecode level), so the class file cannot carry both.

class C {
public:
  def this {}
  def f(x: java.util.List[String]): Int = 1
  def f(x: java.util.List[Integer]): Int = 2   // E0035: both erase to f(List)I
}

Fix: give the overloads different erased signatures (e.g. different arity, or a parameter type that doesn't erase to the same class), or merge them into one method that dispatches internally.

Resolution errors

E0002 — Variable not found

A referenced local variable does not exist in scope. The compiler suggests similar names when possible.

val userName = "ok"
println(usrName)   // E0002, suggests userName

E0003 — Class not found

A type name could not be resolved. Check spelling and imports.

val xs = new ArrayLst[String]()   // E0003, suggests ArrayList

An extension block's receiver type has no [T] type-parameter list of its own (unlike class Box[T]/record R[T]), so a bare identifier written there is resolved as an ordinary type reference, not declared as a fresh type parameter:

extension List[T] {               // E0003: T is not a type, not "List[T]" misspelled
  def second: Object? = ...
}

The diagnostic adds a hint naming the two real options: extension List { ... } extends every instantiation of List (erasure-based), and extension List[Int] { ... } extends one concrete instantiation.

E0004 — Field not found

No field with that name exists on the target type. Check spelling and field visibility.

class Test {
public:
  static def main(args: String[]): Int {
    val s = "a".noSuchField   // E0004
    return 0
  }
}

E0005 — Method not found

No method matches the call. If a method with the same name exists but the argument types differ, the compiler lists the available signatures.

A top-level function is named on its own (a function applicable for helper(Int, Int) is not found), never through the file's synthetic container class. A "did you mean" suggestion names only a member the call could reach — not a library class's private member, and one that takes that many arguments — and prefers one whose parameters also take the argument types. When no such member is close by name, it falls back to the closest-named member that takes a different number of arguments (Strings::trimm(s, 1) suggests trim), still never a library class's private member.

E0006 — Ambiguous method

Two overloads are equally applicable to the call and neither is more specific than the other — often because an argument's static type (e.g. null, or a common supertype) fits multiple unrelated parameter types at once.

class A {}
class B {}
class Test {
public:
  static def foo(x: A): Int = 1
  static def foo(x: B): Int = 2
  static def main(args: String[]): Int {
    foo(null)   // E0006: applicable to both foo(A) and foo(B)
    return 0
  }
}

Fix: cast the argument to pin the overload (foo(null as A)), or rename/merge one of the overloads so only one candidate matches.

E0011 — Duplicated global variable definition

A top-level var/val is declared twice with the same name — whether both are modifier-qualified (static var x = ... twice) or bare (no modifier; a bare top-level var/val is promoted to a public static field of the script's synthetic class, so it is just as global as the modifier-qualified form).

static var x: Int = 1
static var x: Int = 2   // E0011: x already defined

E0012 — Duplicated function definition

Two top-level def functions share the same name and the same parameter types. Overloading by different parameter types is still allowed.

def foo(x: Int): Int { return x }
def foo(x: Int): Int { return x + 1 }   // E0012: foo(Int) already defined

def bar(x: Int): Int { return x }
def bar(x: String): String { return x }   // fine: different parameter types

E0013 — Method not accessible

A private (or otherwise insufficiently visible) method, constructor, or static method is called from outside the class that can see it.

class C {
private:
  static def s(): Int = 1
}
def main(args: String[]): void { IO::println(C::s()) }   // E0013

E0014 — Field not accessible

A non-public field is read or written from outside its declaring class.

class Plain {
  var value: String
public:
  def this(v: String) { value = v }
}
val p = new Plain("orig")
p.value = "changed"   // E0014: value is not public

E0015 — Class not accessible

A member is selected on a value whose static type is an internal class declared in a different module. Accessibility is module-scoped: an internal class is visible only within the module (the dotted prefix before the class name) that declares it.

module pkg.a
internal class Hidden {
public:
  var n: Int
  def this { n = 1 }
}
module pkg.b
import { pkg.a.Hidden }
class UseIt {
public:
  static def main(args: String[]): Int {
    val h: Hidden = null
    return h.n   // E0015: Hidden is internal to pkg.a
  }
}

E0016 — Cyclic inheritance

A class's or interface's supertype chain (extends/conforms) loops back on itself, directly or through an intermediate type.

class A extends B {
}
class B extends A {   // E0016: A -> B -> A cyclicity
}

Fix: break the cycle — one of the two must not extend the other.

E0018 — Illegal inheritance

A class or interface extends/conforms a supertype it isn't allowed to use — either the supertype is final, or an interface position holds a class (or vice versa).

class A extends java.lang.String { public: def this {} }   // E0018: String is final

Fix: extend a non-final class, or use conforms only with interfaces and extends only with a class.

E0019 — Illegal method call

A static method was called through an instance receiver (obj.m(...) or obj?.m(...)) instead of the class itself.

class A {
public:
  def this {}
  static def s(): Int = 1
}
class Test {
public:
  static def main(args: String[]): Int { return new A().s() }   // E0019
}

Fix: call it through the class, A::s().

E0071 — Static call on instance

s::m() was used where s resolves to a local variable, not a type — the Java/Kotlin habit of reaching for :: on an instance. Instead of the generic "type not found", the compiler points at the fix.

class Test {
public:
  static def main(args: String[]): void {
    val s: String = "hi"
    IO::println(s::length())   // E0071: s is a variable, not a type
  }
}

Fix: use . for an instance call (s.length()); :: is only for a type's static members. A real type with the same name as a local still resolves correctly — this only fires when :: is applied to a variable.

E0091 — Class used as a value

The mirror image of E0071: a bare capitalized name that resolves to a real class — not a local variable or field — was used where a value is expected, typically as the target of .member. Instead of the generic "local variable not found", the compiler points at ::.

static def main(args: String[]): void {
  IO::println(System.currentTimeMillis())   // E0091: System is a class, not a variable
}

Fix: use :: for a static member (System::currentTimeMillis()); . is only for an instance's members. A real local variable with the same name as a class still resolves correctly — this only fires when the name resolves to neither a variable nor a field.

E0092 — Cannot instantiate primitive type

new was applied to one of Onion's capitalized primitive type names (Int, Long, Double, Boolean, Byte, Short, Char, Float) — the Java/Kotlin habit of boxing with new Integer(...)/new Double(...). Those names resolve to the primitive BasicType, not a class, so without this check the mismatch surfaced as the generic E0000 "type Object is expected, but type Double is used", with nothing pointing at the fix.

static def main(args: String[]): void {
  val d = new Double(1.5)   // E0092: Double is primitive, not a class
}

Fix: primitive values need no construction — write the literal directly (val d = 1.5). If a boxed java.lang.Object is actually needed, construct the boxed wrapper class instead: JByte, JShort, JCharacter, JInteger, JLong, JFloat, JDouble, or JBoolean.

E0020 — Cannot return value

A bare return; appears in a method whose declared return type isn't void, or a return yields a void-typed expression where a value was expected.

class Test {
public:
  static def f(): Int { return }   // E0020: f must return an Int
  static def main(args: String[]): Int { return 0 }
}

Fix: return a value of the declared type (return 0), or change the method's return type to void.

E0021 — Constructor not found

No constructor matches the arguments. The compiler lists available constructors.

E0022 — Ambiguous constructor

Two constructor overloads are equally applicable to a new call — often because an argument's static type (e.g. null) fits multiple unrelated parameter types at once.

class C {
public:
  def this(a: String) {}
  def this(b: StringBuilder) {}
}
class Test {
public:
  static def main(args: String[]): Int { val c = new C(null); return 0 }   // E0022
}

Fix: cast the argument to pin the overload (new C(null as String)), or rename/merge one of the constructors so only one candidate matches.

E0023 — Interface required

A position that requires an interface type — a forward-delegated field's declared type, or a { ... } closure literal's target type — was given a non-interface (e.g. class) type instead.

class A {
  forward val x: String   // E0023: String is a class, not an interface
public:
  def this { x = "a" }
}

Fix: declare the field/target with an interface type, or drop forward if delegation isn't actually needed.

E0037 — Unimplemented abstract method

A class doesn't provide an implementation for an abstract method declared by an interface it conforms to (or an abstract class it extends), and the class itself isn't declared abstract.

interface I { def m(): Int }
class A conforms I {   // E0037: A must implement m() or be declared abstract
public:
  def this {}
}

Fix: implement the missing method(s), or declare the class abstract.

E0038 — Cannot instantiate abstract class

A new expression targets a class declared abstract, whether or not it declares any abstract methods of its own.

abstract class Shape {
public:
  abstract def area(): Int
}
class Test {
public:
  static def main(args: String[]): Int {
    val s: Shape = new Shape();   // E0038: Shape is abstract
    return 0
  }
}

Fix: instantiate a concrete subclass instead.

E0039 — Cannot override a final method

A method marked override targets a method its superclass declared final.

class A {
public:
  def this {}
  final def m(): Int = 1
}
class B extends A {
public:
  def this {}
  override def m(): Int = 2   // E0039: A.m is final
}

Fix: drop the override, or remove final from the superclass method if overriding was actually intended.

E0068 — Override target not found

A method marked override does not actually override anything — no base class or interface in its supertype chain declares a method of that name (and signature).

class Base {
public:
  def helper(): Int { return 1; }
}
class Sub extends Base {
public:
  override def notInBase(): Int { return 2; }   // E0068: no such method on Base
}

Fix: correct the method name/signature to match the one being overridden, or drop override if it's a new method.

E0072 — Abstract method with a body

A method explicitly declared abstract also has a body. The body would be silently dropped at codegen — abstract and a body are contradictory, so this is rejected rather than compiled into a method that quietly ignores what it says.

abstract class B {
public:
  abstract def foo(): Int { return 99 }   // E0072: abstract method cannot have a body
}

Fix: remove abstract to keep the body (a concrete method), or remove the body to leave it abstract. An interface's default method (a body with no abstract keyword) is unaffected.

E0040 — Cannot call method on primitive type

A method call's target expression has void type — typically chaining a call directly onto the result of another call that returns nothing.

class Test {
public:
  static def main(args: String[]): Int {
    IO::println("a").toString()   // E0040: println returns void
    return 0
  }
}

Fix: split the two calls into separate statements.

E0041 — Invalid method call target

A method call (or [...] indexing) targets an expression whose type isn't a usable receiver — for example a nullable class-typed value (T?) that hasn't been unwrapped, or a wildcard type with no concrete upper bound.

class Box {
public:
  def this {}
}
class Test {
public:
  static def main(args: String[]): Int {
    val b: Box? = null;
    val v = b[0];   // E0041: Box? is not a valid method call target
    return 0
  }
}

Fix: exclude null first (if b != null { ... }, b ?: default, or b?.method()/b?[...]) so the receiver has a definite, non-null type.

E0061 — Record component type unsupported by from re"..." or a shape clause

A record ... from re"..." clause derives parse/parseAll by converting each regex capture group to its component's type. Only String, Int, Long, Double, Float, Boolean, Short, and Byte components can be produced this way.

record Inner(x: Int)
record R(a: String, b: Inner) from re"(\S+) (\S+)"   // E0061: Inner is not a supported component type

A shape name = ... clause (regex, yaml or config) reads its components the same way, so the same restriction applies; the message names the clause that could not produce the component (shape line = re"...", from re"...").

from re"..." and a regex/yaml/config shape also accept T? of any of those scalars — the capture group (or key) may be absent, and the component is then null instead of the non-null sentinel ("" for String) a missing non-nullable component still gets. T? is only accepted when the inner type T is itself a supported scalar; Inner? for an unsupported Inner is still E0061. derive!(Json, Yaml) accepts T? too, with the same null-for-absent semantics — see E0062.

A shape name = json clause reads more: besides the scalars, List[S] of a scalar, a record R that declares a json shape of its own, List[R], and T? of any of these. Anything else is still E0061 for it — a Map, an array, List[List[S]], List[S?], a record with no json shape, or a type alias standing for one of the accepted types:

record Inner(x: Int)                                   // no json shape
record R(a: String, b: Inner) { shape doc = json }     // E0061: shape doc = json cannot read Inner

Every shape of a record reads the same components, so a record whose json shape reads a List[String] but which also declares shape line = re"..." is E0061 naming the regex clause.

Fix: keep every component in the supported scalar set (or, for a json shape, in the extended set above — give a nested record its own shape doc = json), or parse the field manually after a plain from re"..." match on the rest.

E0062 — Record component type unsupported by derive!

derive!(Json) and derive!(Yaml) both generate their fromX/toX pair by mapping each component to a scalar — they share the same toMap/fromMap core, so the restriction is identical for both. Only String, Int, Long, Double, Float, Boolean, Short, and Byte components are supported — the same set as from re"..." — plus T? of any of them (#1969).

record Inner(z: Int)
record Bad(a: String, b: Inner) derive!(Json)   // E0062: Inner cannot be serialized

A nullable component reads a missing key or a JSON/YAML null as null, and writes a null value back as a real JSON/YAML null (not an omitted key). A present key whose value is the wrong type still fails the whole record, same as a missing non-nullable one does — nullability only makes absence a value, not a wrong type:

record Person(name: String, nickname: String?) derive!(Json)
Person::fromJson("{\"name\": \"Ko\"}")                 // ok: nickname() is null
Person::fromJson("{\"name\": \"Ko\", \"nickname\": 5}") // null: nickname present as a number

Fix: keep every component in the supported scalar set (T or T? of one).

E0063 — Unknown derive! marker

derive!(...) names a format the compiler does not implement. The supported markers are Json and Yaml — either alone, or together as derive!(Json, Yaml).

record U(a: String) derive!(Bogus)   // E0063: unknown derive! marker Bogus

Fix: use derive!(Json), derive!(Yaml), or derive!(Json, Yaml), or remove the clause.

E0086 — Duplicate record component

Two components of the same record declare the same name. Each component name generates a private field and a public accessor method, so a repeated name would collide with itself — left unchecked, this only failed once something loaded the generated class (a ClassFormatError, surfaced as an internal I0000 error) rather than at compile time.

record R(a: Int, a: Int)   // E0086: duplicated record component a in R

Fix: rename one of the components.

E0073 — Map cannot be iterated directly

foreach walks an array or something with an iterator(); a Map has neither.

val m = ["a": 1]
foreach k: String in m { println(k) }   // E0073

Iterate the entries with the destructuring form, or pick a view:

foreach (k, v) in m { println(k + "=" + v) }
foreach k: String in m.keySet() { println(k) }

E0076 — Unknown shape format

A shape name = <format> clause names a document format the compiler does not know. Guessing would produce a shape that silently reads nothing, so it is an error listing what is supported.

record Pt(x: Int, y: Int) {
  shape doc = toml     // E0076: supported formats are json, yaml, config
}

For an inline pattern, write shape name = re"...".

Capability errors

A tool declaration draws a boundary with a requires { ... } clause; the compiler infers the whole body's effects (transitively, through ordinary functions) and checks the declaration against them.

E0077 — Tool performs an undeclared effect

The body performs an effect the requires clause does not cover. The diagnostic names the missing effect, the callee, and the call site.

tool sneaky(src: String, dst: String): void
  requires { read(src) }
{
  Files::writeText(dst, Files::readText(src))   // E0077: performs `write` (writeText)
}

Fix: add the missing capability — requires { read(src), write(dst) }.

E0078 — Declared capability the body cannot perform

A capability in requires is unused: nothing in the body performs it. An honest boundary lists only what actually happens.

tool overclaim(src: String): String
  requires { read(src), net }   // E0078: `net` is unused
{
  return Files::readText(src)
}

Fix: remove the unused capability.

E0079 — Invalid capability entry

A requires entry is not a valid capability: an unknown effect name, a parameter argument on an effect that is always ambient, or an argument that does not name one of the tool's parameters.

tool t(): Int requires { teleport } { return 0 }
  // E0079: `teleport` is not an effect

tool t2(x: String): Int requires { console(x) } { IO::println(x); return 0 }
  // E0079: `console` does not take a parameter argument

tool t3(src: String): String requires { read(nope) } { return Files::readText(src) }
  // E0079: `nope` does not name a parameter

The effect vocabulary is read write net exec env clock rand console unknown; only read, write, net, and exec take a parameter argument.

Null-safety errors

E0057 — Type parameter may be null

A bare type parameter [T] can be instantiated with a nullable type, so direct dereference is not allowed without a null-check or a non-null bound.

class Box[T] {
public:
  def size(x: T): Int = x.toString().length()   // E0057
}

Fixes: - Use ?. / ?: / if x != null. - Declare a non-null bound: class Box[T extends Object].

E0070 — Nullable value used without a null check

A value of nullable type (T?) was used somewhere that requires it to be definitely non-null, with no null-check in between. This one code covers several forms, sharing the same fix:

  • Member access — a field (not method) accessed directly on a nullable receiver (x.length where x: String?).
  • Indexing — b[i] / b[i] = v / b[i] += v on a nullable array, List, or Map (b: List[Int]?).
  • Operators — a nullable operand of a unary (-n, +n, ~n, !b), binary (+ - * / % < > <= >= & | ^), shift (<< >> >>>), post-increment/decrement (n++ / n--), or compound-assignment (n += 1, n <<= 1, ...) operator.
  • Condition — a nullable Boolean? used directly as an if / while / do-while / for condition, or a select guard's when.
  • foreach collection — foreach x: T in expr where expr has nullable type.
  • Destructuring — val (a, b) = expr where expr is a nullable record.
  • Array size — new T[n] where a dimension n has nullable type (n: Int?).
  • try-with-resources initializer — try (val r = res) { } where res has nullable type.
  • throw operand — throw expr where expr has nullable type.
  • select scrutinee — select s { ... } where s has nullable type (only when there's neither an else clause nor an unconditional wildcard pattern -- either one already handles a null scrutinee correctly).
  • Range bound — a..b / a..<b where a or b has nullable type (these desugar to a Range constructor call, so a nullable bound is rejected the same way as any other dereference-like use).
  • Assignment / declaration — a nullable value assigned where a non-null type is expected: a val/var declaration's initializer, a return value, a plain reassignment, or a field initializer (a target that itself accepts null -- a nullable-typed declaration, or a bare/platform type parameter -- is unaffected).
  • catch clause type — catch e: E? where the declared exception type is nullable. Unlike the forms above, there is no value to null-check here -- a caught exception is never null, so the fix is to drop the ? from the catch clause's declared type.
class Test {
public:
  static def main(args: String[]): Int {
    val x: String? = "abc"
    return x.length   // E0070: x may be null
  }
}

Fix: use ?. / ?[ to access it safely, ?: to supply a default, !! to assert non-null, or check for null first (if x != null { ... }).

Special case — a top-level script var: unlike a top-level val or a method-local var, a top-level script var is never narrowed by a null check, because it is promoted to a mutable field rather than a local variable:

var s: String? = "hi"
if s != null {
  IO::println(s.length)   // E0070, even though the check right above is exactly the fix
}

The diagnostic adds a hint naming the actual workaround -- copy the value to a local first: val t = s, then use t. Whether this case should be narrowed like the others is an open design question (#2026, #2031); this is a diagnostics-only fix, not a semantics change.

E0081 — Tool parameter cannot be read from the command line

A tool's parameters must all be readable from a command-line argument, since the CLI is derived from them.

record P(x: Int)

tool takeRec(p: P): Int requires { console } { IO::println("" + p.x()); return 0 }
// E0081: parameter `p` has type P, which cannot be read from an argument.
//        Supported: String, Int, Long, Double, Float, Boolean, Short, Byte.

This used to be silent: CLI synthesis skipped such a script, which then compiled to a program with no main and nothing to run (issue #424).

A List[String] or String[] parameter gets a message of its own: a tool cannot take a list of arguments yet. Take one flag and split it:

tool greet(csv: String = "") requires { console } {
  if csv != "" {
    foreach n: String in Strings::split(csv, ",") { IO::println("Hello, " + n) }
  }
}
// $ onion greet.on --csv ann,bob

E0082 — Duplicate tool name

Two tools share a name. Function overloading is fine, but the command line selects a tool by name alone, so the second one can never be invoked and --contract lists both under the same name with no way to address either.

tool same(a: Int): Int requires { console } { IO::println("A"); return 0 }
tool same(b: String): Int requires { console } { IO::println("B"); return 0 }
// E0082: duplicate tool name `same`.

E0093 — Two parameters answer to the same command-line flag

A flag parameter of a def main auto-CLI or a tool is accepted both under its own name and in kebab-case (makeSample answers to --makeSample and --make-sample). When two flag parameters share a spelling, one of them could never be set, so the second one is reported at compile time instead of being resolved silently at run time.

def main(parseURL: Int = 1, parseUrl: Int = 2): void { IO::println(parseURL + parseUrl) }
// E0093: parameters `parseURL` and `parseUrl` of `main` would both answer to the
//        command-line flag `--parse-url`.

Rename one of them. Positional parameters (those without a default) have no flag and are not checked.

E0094 — main parameter has a type auto-CLI cannot read

A top-level auto-CLI main parameter's type is neither a supported scalar (String, Int, Long, Double, Float, Boolean, Short, Byte) nor, as the last parameter, a String[] rest collector.

def main(name: String, count: Int = 3, tags: List[String] = []): Int {
  return 0
}
// E0094: `main` cannot derive a command line: parameter `tags` has type
//        List[String], which cannot be read from an argument.

Use a scalar, or String[] as the last parameter to collect repeated/trailing arguments (e.g. def main(cmd: String, files: String[])).

A varargs parameter (files: String...) is E0094 too: write files: String[]. A tool reports the same mistake as E0081.

E0095 — main's String[] parameter is misplaced

A top-level auto-CLI main has a String[] parameter that is not in a supported position: not the only parameter (raw argv) and not the last parameter (a rest collector preceded only by required scalars).

def main(args: String[], flag: Boolean = false): void {
  IO::println("BODY RAN")
}
// E0095: `main` has a String[] parameter, `args`, that is not in a supported
//        position.

A String[] parameter must be either the only parameter, or the last parameter with no default value, preceded only by required (no-default) scalar parameters.

Try/catch errors

E0083 — Unreachable catch clause

A later catch clause whose exception type is already a subtype of (or the same as) an earlier clause's type can never run — the earlier clause handles it first.

try {
  risky()
} catch e: RuntimeException {
  handle(e)
} catch e: IllegalArgumentException {
  // E0083: IllegalArgumentException is a RuntimeException, already caught above
}

Reorder so the more specific type comes first, or remove the unreachable clause. The alternatives of a single multi-catch clause (catch e: A | B) are not checked against each other.

Extension method errors

E0084 — Duplicate extension method

Two methods with the same name and parameter types are declared in the same extension block. Left unchecked, the generated container class would carry two methods with an identical JVM signature, which only fails once something loads the class (a ClassFormatError, surfaced as an internal I0000 error) rather than at compile time.

extension Double {
  def pct(): String = "" + self
  def pct(): String = "" + self   // E0084: duplicated extension method pct() on Double
}

Fix: remove or rename the duplicate. Two extension methods with the same name but different parameter types are unaffected — that's ordinary overloading.

E0102 — Duplicate extension block for the same receiver type

Two extension blocks for the exact same receiver type appear in one file — whether the identical concrete instantiation written twice, or the same non-generic type split across two blocks (e.g. one per concern, for readability). Both would lower to the same generated container class, so without this check the second block collided later as a generic duplicate-class error naming the internal mangled class (Extension$List_int), and every method the second block declared was then silently unreachable — reported, if at all, through an unrelated "method not found" at the call site.

extension List[Int] { def foo(): Int = 1 }
extension List[Int] { def bar(): Int = 2 }   // E0102: an extension block for List[int] is already defined

Fix: combine the methods into the first block. Distinct concrete instantiations of the same generic receiver do not collide (extension List[Int] and extension List[String] can coexist).

E0103 — foreach (a, b) over something that is not a Map

foreach (a, b) in xs walks the entries of a Map (or of any class with its own entrySet()). When xs is of another type, such as a List, an array or a record, it is this one error, at the foreach. This holds for any xs: a variable, a field, a call result or a literal. It used to report entrySet() not found and an operator error on K, V, names you never wrote.

record P(x: Int, y: Int)
val ps = [new P(1, 2), new P(3, 4)]
foreach (x, y) in ps { println(x + y) }   // E0103: this is List[P], not a Map

Fix: take each element apart with val (a, b) = p.

foreach p in ps { val (x, y) = p; println(x + y) }

E0104 — Override changes a primitive return type

A method, or a record component's accessor, overrides an inherited method with a different return type, and one of the two types is primitive. The JVM matches an override by its exact descriptor, so Int does not override Double or JInteger. Calls through the supertype would run the inherited method instead.

interface Shape { def area(): JInteger }
record Circle(area: Int) conforms Shape   // E0104: area(): Int cannot override Shape.area(): JInteger

Fix: give the component or method the inherited type (area: JInteger), or rename it.

E0105 — A contract clause while contracts are off

A requires, ensures, invariant or history clause appears in a program compiled with --contracts off (the default is check). Contracts are a preview feature (RFC #2557). The clause is an error rather than being ignored: a contract that silently does nothing is worse than none.

class Counter {
  var n: Int
public:
  def get(): Int ensures result == n { return n }   // E0105: contracts are off
}

Fix: compile with --contracts check, or remove the clause.

E0106 — A contract that is not pure

A contract expression calls something that does I/O, writes memory, or that the effect inference cannot vouch for. A contract states what holds; it may not change anything. A call to a method of the program is allowed when that method is pure.

import { java.util.* }
class A {
public:
  def f(xs: List[Int]): Int requires xs.add(1) { return 0 }   // E0106: List.add writes to memory
}

Fix: call a pure method (xs.size, xs.get(0)), or move the work out of the contract.

E0107 — old(...) out of place

old(e) is the value of e on entry to a method. It means that only in an ensures or a history. In a requires or an invariant there is no earlier state to look at.

class A {
  var n: Int
public:
  def f(): void requires old(n) > 0 { }   // E0107
}

Fix: use the plain value in a requires, or move the condition to an ensures.

E0108 — a history that is not a preorder

A history relates two states of one object. It must be reflexive (h(a, a) holds) and transitive, so that checking one call at a time checks the whole life of the object. n == old(n) + 1 is neither; n > old(n) is not reflexive.

class A {
  var n: Int
  history n == old(n) + 1   // E0108
  history n >= old(n)       // ok
}

Fix: use x >= old(x), x <= old(x) or x == old(x).

E0109 — a write that can break a history

history n >= old(n) says n never decreases. A method that lowers n, or that sets n to a constant while another method raises n, can break it. This is the case a subtype's reset creates: it keeps every precondition and postcondition and still breaks the history.

class Counter {
protected:
  var n: Int
  history n >= old(n)
public:
  def this { n = 0 }
  def inc(): void requires n < 2147483647 { n = n + 1 }
}
class ResettableCounter extends Counter {
public:
  def reset(): void { n = 0 }   // E0109: inc raises n, so n can be above 0
}

Only what the syntax settles is reported. Fix: remove the write, or weaken the history.

A write counts wherever the method makes it, also inside a lambda it creates. A write in a lambda that the syntax does not settle gets the warning W0024 at its line. A write through another object (o.n = 0) is E0110, below.

A history declared in a subclass also binds the methods the subclass inherits without overriding them. If class Up extends Base declares history n >= old(n), an inherited Base.dec that lowers n is E0109 at its write. Fix: override dec in Up, or declare the history in Base and make dec keep it. A private method counts too: it is checked when an inherited method calls it, and the error names that method. An inherited write the syntax does not settle gets W0024.

E0110 — an invariant or history on a mutable object, or its field written through another object

A clause may name only fields of a primitive, String, enum or record type. A List or another class can change without this class running, so the clause could not be checked one call at a time.

class A {
  var items: java.util.List
  invariant items != null   // E0110
}

Fix: name a value-typed field, or a pure method that reads the object.

A field a clause names is written only through this (bare n, this.n or self.n). A write through any other reference is E0110, whatever its declared type, because no check of one call at a time can follow it:

class Counter {
protected:
  var n: Int
  history n >= old(n)
public:
  def this { n = 0 }
  def copyFrom(o: Counter): void { o.n = n }                      // E0110
  static def at(k: Int): Counter { val c = new Counter(); c.n = k; return c }   // E0110
}

Fix: call a method of that object, whose own writes are checked, or set the value in a constructor (def this(k: Int) { n = k }).

E0111 — an invariant or history on a class with a Java superclass

A Java superclass can have methods that change state, and the compiler can neither prove nor guard them. Extend only Object or an Onion class.

class A extends java.util.ArrayList[String] {
  invariant size >= 0   // E0111
}

E0112 — a history that breaks when the code runs

The solver found a state in which a method breaks a history, and running the compiled code from that state confirms it. n = n + 1 against history n >= old(n) breaks at n = 2147483647, where n + 1 wraps to a negative number.

Fix: add an invariant or a requires that rules the state out, or weaken the history. A counterexample that does not break when run stays the warning W0021.

E0113 — a closed predicate that is false

A static def with no parameters that returns Boolean and has an ensures clause is run when the build runs. It must return true. This replaces a false example.

def sums(): Boolean
  ensures result
  = 1 + 1 == 3   // E0113: false when the build runs it

Fix: correct the expression, or the code it checks.

The build runs a predicate only when its effects are at most mutate. One that prints, reads or writes files, or calls something the effect table cannot vouch for (unknown) is not run: it gets the warning W0023 instead. So does one that does not finish within 10 seconds. The effects count everything a run can reach:

  • every overload with the predicate's name and parameter count
  • an override or interface implementation the program defines
  • a method the library calls back on a program value: toString from + and #{}, hashCode from a map literal, equals from ==, getMessage of a thrown exception
  • the static initializer of each class the predicate uses, and of its superclasses
  • for a parameter of a program class (Foo or Foo?): that class's constructors, static initializers and toString, which the build runs to make sample arguments, and the same for the classes of their parameters

An E0112 replay follows the same rule. When it is not run, or does not finish in time, the W0021 for that method stays, and W0023 says why the build did not confirm it.

When the effect is not in the predicate's own body, W0023 names where it is: the call, the class whose static initializer has it, or the parameter's class.

E0114 — a Shape that does not round-trip

Every onion.Shape has a contract: parse(print(v)) must equal v for each value the shape can print. The build samples values of the shape's value type and checks it. A value that does not come back is E0114, with the value and the --contract-seed / --contract-samples to reproduce it.

class FixedWidth conforms Shape[Person] {
public:
  // ... print pads `name` to 10 columns and does not cut it ...
  def printable(v: Person): Boolean =   // states the domain; the default admits every value
    v.name().length() <= 10 && v.name() == v.name().trim()
}

Fix: override printable to say which values the shape can print, or fix print / parse. A shape with canPrint() == false owes nothing. A value type that cannot be sampled is the warning W0022, never a silent pass.

E0115 — super call to an abstract method

super.f() runs the superclass's own body. If f is abstract there, or is left open by an abstract class that implements an interface, there is no body to run. Without this error the call compiled and threw AbstractMethodError.

abstract class Base {
public:
  abstract def f(): Int
}
class Child extends Base {
public:
  override def f(): Int = 2
  def g(): Int = super.f()   // E0115
}

Fix: call the override on self (f()), or give the superclass method a body.

Declaration errors

E0007 — Duplicate local variable

The same name is declared twice as a local variable in the same scope.

class Test {
public:
  static def main(args: String[]): Int {
    val x = 1
    val x = 2   // E0007: x is already declared in this scope
    return 0
  }
}

Fix: rename one of the variables, or drop the redundant declaration.

E0008 — Duplicate class

Two top-level classes (or interfaces/records/enums) share the same name.

class A { public: def this {} }
class A { public: def this {} }   // E0008: A is already declared

Fix: rename or remove one of the declarations.

E0009 — Duplicate field

The same field name is declared twice on a class.

class A {
  var x: Int
  var x: Int   // E0009: x is already declared on A
public:
  def this {}
}

Fix: remove the duplicate field, or give it a different name.

E0010 — Duplicate method

Two methods on the same class share an identical name and parameter list, so neither is a valid overload of the other.

class Test {
public:
  def m(): Int = 1
  def m(): Int = 2   // E0010: m() is already declared on Test
  static def main(args: String[]): Int { return 0 }
}

Fix: rename one method, or give it different parameter types to make it a genuine overload.

A record component already generates its accessor, so a record body cannot define a zero-argument method of the same name, whatever its return type or modifiers:

record R(a: Int) {
public:
  def a(): Int = 42   // E0010: component a: Int already generates a(): Int
}

Fix: rename the method or the component. A method a(x: Int) with parameters is a genuine overload and compiles.

Every record also generates public instance methods equals(Object), hashCode() and toString(). A body method with one of those signatures replaces the generated one only when it is a public or protected instance method. A static one, or a private one, is E0010, because == and string conversion could not call it:

record R(name: String) {
public:
  static def toString(): String = "s"   // E0010: clashes with the generated toString()
}

Fix: remove static (or move the method under public:) to replace the generated method, or rename it.

E0025 — Duplicate constructor

Two constructors on the same class have identical parameter types, so neither is a valid overload of the other.

class A {
public:
  def this(x: Int) {}
  def this(y: Int) {}   // E0025: this(Int) is already declared on A
}

Fix: give one constructor different parameter types, or remove the duplicate.

E0026 — Duplicate generated method

A record's law/example clauses synthesize a check method per clause, named after the clause. Two law (or two example) clauses with the same name and the same parameter types mangle to the same method, colliding at codegen. Without this check the collision surfaced later as a raw JVM ClassFormatError instead of a normal diagnostic.

record Point(x: Int, y: Int) from re"(-?\d+),(-?\d+)" {
  law roundtrip(p: Point) { Point::parse(Point::format(p)) == p }
  law roundtrip(p: Point) { Point::parse(Point::format(p)) == p }   // E0026
}

Fix: rename one of the clauses, or remove the duplicate.

E0029 — Duplicate type parameter

The same type parameter name appears twice in one class, interface, or method's type parameter list.

class Box[T, T] { public: def this {} }   // E0029: T is already declared

Fix: give the type parameters distinct names.

E0051 — Return type is required

A top-level function or extension method has no declared return type, and the compiler cannot infer one — typically because the function is self-recursive, so there is no already-typed body to infer the type from.

def f(n: Int) = f(n)   // E0051: f needs an explicit return type
def main(): void { }

Fix: give the function an explicit return type, e.g. def f(n: Int): Int = f(n).

E0052 — Lambda parameter must specify a type

A lambda parameter has no type annotation, and the context the lambda appears in gives the compiler no functional-interface type to infer the parameter's type from.

val f = (x) -> x + 1   // E0052: x's type can't be inferred here
def main(): void { }

Fix: annotate the parameter explicitly ((x: Int) -> x + 1), or use the lambda where its target type is known — e.g. passed directly as an argument to a method with a declared function-typed parameter.

E0053 — Cyclic type alias

Two or more type aliases refer to each other, so resolving any of them would recurse forever.

type A = B
type B = A   // E0053: A -> B -> A

Fix: break the cycle by pointing at least one alias at a concrete type.

E0054 — Duplicate type alias

The same type alias name is declared twice at the same scope.

type A = java.lang.String
type A = java.lang.Integer   // E0054: A is already declared

Fix: rename or remove one of the declarations.

E0055 — Function requires a body

A top-level function was declared without a body (no { ... } and no = expr). Unlike a class method, a top-level function can never be abstract, so it must always carry an implementation.

def f(): Int;   // E0055: f requires a body
def main(): void { }

Fix: give the function a body.

E0085 — Static method with no body

A method declared static has no body (no { ... } and no = expr). The grammar also accepts a bodyless method as an abstract/interface-style declaration, but static and abstract are contradictory — a static method cannot be overridden, so it cannot be abstract either. Generating a class file for one would need both ACC_STATIC and ACC_ABSTRACT, which the JVM rejects.

class LineFilter {
public:
  static def main(args: String[]): void
  // E0085: static method main must have a body
}

Fix: add a body, or drop static to declare an ordinary abstract instance method.

E0096 — Private abstract method

An abstract method (a bodyless def) is private. A member declared before any public:/protected: section is private, as is anything under private:, and a private method cannot be overridden, so no subclass could ever implement it. The JVM rejects the combination ACC_PRIVATE|ACC_ABSTRACT.

abstract class Shape {
  abstract def area(): Double
  // E0096: abstract method area cannot be private ...
}

Fix: declare it under public: or protected:.

E0097 — Duplicate instance for the same (trait, type)

Two instance declarations for the same trait application (e.g. Numeric[Integer] declared twice) appear in one compilation unit. At most one instance per (trait, type) is allowed — both would lower to the same mangled class name.

trait Numeric[T] { def zero(): T }
instance Numeric[Integer] { def zero(): Integer = 0 }
instance Numeric[Integer] { def zero(): Integer = 1 }
// E0097: instance Numeric[Integer] is already defined ...

Fix: remove or merge the duplicate. A primitive and its boxed type (e.g. Int and Integer) are the same erased instance, so they collide too.

E0098 — ADT enum mixes shared parameters with case cases

A Scala-3-style ADT enum (one with case cases) also declares its own shared constructor parameters. ADT enums carry fields per case only, via the generated record for each case; enum-level shared parameters mixed with case cases is a separate, unimplemented feature.

enum Mixed(tag: String) {
  case A(x: Int)
  case B
}
// E0098: enum Mixed mixes shared parameters with `case` cases ...

Fix: move the shared data into each case's own fields, or drop the case cases in favor of a homogeneous, data-carrying enum (enum Mixed(tag: String) { A, B }).

E0099 — Homogeneous enum with type parameters

A homogeneous enum (no case cases) declares type parameters. A homogeneous enum compiles to a java.lang.Enum, which the JVM does not allow to be generic; only an ADT enum (one with case cases, desugared to a sealed interface + records) can be generic.

enum Color[T] { RED, GREEN }
// E0099: enum Color cannot take type parameters ...

Fix: drop the type parameters, or restructure as an ADT (case) enum if each case genuinely needs its own type argument.

E0100 — Multiple binding patterns comma-joined in one case

A select case's comma-joined pattern list has 2+ alternatives where at least one is a type pattern, destructuring pattern, regex pattern, or bare binding pattern. The generated code can only use one alternative's binding/cast, so a sibling alternative that actually matches at runtime — another type pattern, or even a bare wildcard (_), which matches regardless of the recorded binding's type — gets miscast to that one alternative's type.

enum Shape { case Circle(radius: Double); case Square(side: Double); case Triangle(base: Double, height: Double) }
def isRound(sh: Shape): Boolean {
  return select sh {
    case c is Circle: true
    case s is Square, t is Triangle: false   // E0100: only Triangle's binding survives
    else: false
  }
}
isRound(new Square(2.0))   // would throw: class Square cannot be cast to class Triangle

Fix: write each such alternative as its own case clause instead:

def isRound(sh: Shape): Boolean {
  return select sh {
    case c is Circle: true
    case s is Square: false
    case t is Triangle: false
  }
}

A comma-joined list of plain value patterns (case 1, 2, 3:) is unaffected — only a type, destructuring, regex, or bare binding pattern triggers this.

E0101 — Lambda has the wrong number of parameters

A lambda's parameter count differs from that of the function type expected for it. The message gives both counts and the expected type.

val m = ["a": 1, "b": 2]
m.filter { e -> e.getValue() > 0 }      // E0101: Map's filter takes (key, value)
[1, 2].fold(0) { acc -> acc }           // E0101: fold's function takes (acc, element)

Fix: write the lambda with the parameters the function type takes — m.filter { k, v -> v > 0 }, [1, 2].fold(0) { acc, x -> acc + x }.

E0069 — Local val requires an initializer

A local val was declared without an initializer (no = expr). Unlike a var, a val can never be assigned later, so a val with no initializer could only ever read the JVM's zero-value default — a bug, not a value.

class Test {
public:
  static def main(args: String[]): Int {
    val x: String   // E0069: x is never initialized
    IO::println(x)
    return 0
  }
}

Fix: give it an initializer at the declaration (val x: String = ...), or use var if the value genuinely needs to be assigned later. A field val initialized in the constructor is unaffected.

Constructor errors

E0087 — Secondary constructor must delegate to the primary

A class with a primary constructor — a parameter list after the class name, or arguments on the extends clause, or both — declares a def this that does not delegate to it with : this(...). The primary constructor is the only place the superclass constructor is called and the only place the val/var parameter fields are stored; a constructor that goes around it reaches the superclass with an implicit super() the class never wrote and leaves those fields at their defaults. Before this check, class P(val x: Int) { def this { } } compiled and new P().x was 0.

class Point(val x: Int, val y: Int) {
public:
  def this(x: Int) { }   // E0087: must delegate — write `: this(x, 0)`
}

Fix: add the delegation, def this(x: Int) : this(x, 0) { }. A class with no primary constructor is unaffected: its def this constructors call the superclass no-arg constructor as they always did.

E0088 — Constructor delegation cycle

Two or more constructors delegate to each other in a cycle, so no path ever reaches a constructor that calls the superclass. At new this is a StackOverflowError.

class C {
public:
  def this(a: Int) : this("s") { }   // E0088
  def this(s: String) : this(1) { }
}

Fix: make one constructor in the cycle the one that does not delegate (or, in a class with a primary, delegate to the primary).

E0089 — Constructor in a record or enum body

A def this inside a record or enum body. Both have their canonical constructor generated from their component or parameter list, and there is nothing a second constructor could mean. This used to be a compiler crash rather than a diagnostic: the body was never typed, and code generation then emitted the record's parameter-to-field stores against a constructor of the wrong arity.

record R(a: Int, b: Int) {
public:
  def this(a: Int) { }   // E0089
}

Fix: use a static factory method (static def of(a: Int): R = new R(a, 0)).

E0090 — this before constructor delegation

this — explicitly, or through a bare field name — is used inside the argument list of a : this(...) delegation or an extends B(...) super call. The object does not exist yet at that point: the JVM verifier rejects a field read on uninitializedThis, so without this check the program compiled to a class that failed to load, reported as an internal error. Java's "cannot reference x before supertype constructor has been called" is the same rule.

class F(val x: Int) {
public:
  var seed: Int = 3
  def this : this(seed) { }   // E0090: `seed` is a field of the not-yet-built object
}

Fix: pass a parameter or a constant. A closure in that position is fine — it captures this and runs later, when the object exists.

Control-flow errors

E0048 — Break outside loop

A break (labeled or not) appears outside any enclosing loop.

class Test {
public:
  static def main(args: String[]): Int {
    break   // E0048: no enclosing loop
    return 0
  }
}

Fix: only use break inside a while, for, or foreach loop.

E0049 — Continue outside loop

A continue (labeled or not) appears outside any enclosing loop.

class Test {
public:
  static def main(args: String[]): Int {
    continue   // E0049: no enclosing loop
    return 0
  }
}

Fix: only use continue inside a while, for, or foreach loop.

E0050 — Current instance not available in static context

this/self was used inside a static method, where there is no receiver instance.

class Test {
public:
  static def s(): Int { return this.hashCode() }   // E0050: s is static
  static def main(args: String[]): Int { return 0 }
}

Fix: drop static, or pass the instance in explicitly as a parameter.

super inside an extension method is also E0050, with its own message: the receiver is this, so call the method on it.

E0058 — Label not found

A labeled break/continue names a label that is not bound to any enclosing loop.

class Test {
public:
  static def main(args: String[]): void {
    foreach i: Int in 0..3 {
      break nosuch   // E0058: no enclosing loop labeled nosuch
    }
  }
}

Fix: label the target loop (outer: foreach ... { break outer }), or correct the spelling of the label.

Pattern-matching errors

E0042 — Non-exhaustive pattern match

A select on a sealed type does not cover all cases.

sealed interface Shape {}
record Circle(r: Int) conforms Shape
record Rect(w: Int, h: Int) conforms Shape

select shape {
  case Circle(r): println("circle")
  // missing Rect case → E0042
}

E0043 — Unknown named argument

A call used name = value syntax for an argument name that does not match any parameter of the resolved method, constructor, or function.

class T {
public:
  static def f(x: Int, y: Int): Int = x + y
  static def main(args: String[]): Int { return f(x = 1, nope = 2) }   // E0043: f has no parameter named nope
}

Fix: check the argument name's spelling against the target's declaration.

E0044 — Duplicate argument

The same parameter was bound twice in one call — for example by a named argument that repeats a name already used earlier in the same call.

class Test {
public:
  static def f(x: Int, y: Int): Int = x + y
  static def main(args: String[]): Int { return f(x = 1, x = 2) }   // E0044: x is already bound
}

Fix: remove the duplicate binding.

E0045 — Positional argument after named argument

A call places a positional argument after a named one. Once a call starts naming arguments, every argument after that point must also be named — otherwise it is ambiguous which parameter the positional value fills.

class Test {
public:
  static def f(x: Int, y: Int): Int = x + y
  static def main(args: String[]): Int { return f(x = 1, 2) }   // E0045: 2 comes after a named argument
}

Fix: name every remaining argument, or move the positional ones first.

E0046 — Wrong number of bindings in destructuring pattern

A destructuring val/var (a, b, ...) declaration (or a nested destructuring pattern) named a different number of variables than the record has components.

record Point(x: Int, y: Int)
class Test {
public:
  static def main(args: String[]): Int {
    val (a, b, c) = new Point(1, 2)   // E0046: Point has 2 fields, 3 bindings given
    return 0
  }
}

Fix: match the binding count to the record's component count.

E0047 — Not a record type

A destructuring val/var (a, b, ...) = expr was used against a value whose type is not a record, so there are no positional components to bind.

class Test {
public:
  static def main(args: String[]): Int {
    val (a, b) = "not a record"   // E0047: String is not a record type
    return 0
  }
}

Fix: destructure a record value, or bind the whole value with a plain val/var instead.

E0059 — Invalid regex literal

A re"..." literal (bare, in a select case, or in a from re"..." clause) is not a well-formed regular expression. It is validated at compile time so a bad pattern is caught there instead of throwing PatternSyntaxException at run time.

val p = re"(unclosed"   // E0059: invalid regular expression literal

Fix: correct the pattern.

E0060 — Regex capture group / binding count mismatch

A case re"..." (b1, b2, ...) pattern (or a record ... from re"..." clause) named a different number of bindings/components than the pattern has capture groups.

select "x" {
  case re"(\d+)-(\d+)" (a): a   // E0060: pattern has 2 groups, 1 binding given
  else: "no"
}

Fix: match the binding (or record component) count to the pattern's capture group count.

Parser errors

Parser errors do not carry E codes; they report the encountered token and the expected tokens.

Test.on:2:10: Syntax error. Encountered "{", but expecting ";"

Warnings

Unlike E codes, W codes don't fail compilation by default (--warn error turns them into errors) and can be suppressed individually with --Wno (see Compiler tools for the --Wno name of each code).

A code marked (reserved) is declared and can be named with --Wno, but no compiler pass reports it yet -- it can never actually appear in a build log.

Code Meaning
W0001 unused variable
W0002 unused import (reserved)
W0003 unreachable code
W0004 deprecated feature (reserved)
W0005 shadowed variable
W0006 unused parameter
W0007 empty block (reserved)
W0008 redundant cast (reserved)
W0009 possible null dereference (reserved)
W0010 unnecessary type conversion (reserved)
W0011 unchecked cast: e as D where the run-time check cannot test D's type arguments (o as List[String]) or a type-variable D (o as T); an upcast, all-Object arguments and a downcast whose arguments follow from the source (ls as ArrayList[String]) do not warn
W0012 null assigned to non-nullable type
W0013 suspicious string interpolation syntax
W0014 top-level statements ignored because a main is defined
W0015 boxed platform value implicitly unboxed to a non-null primitive
W0016 @TailRecursive annotation present but its mutual-recursion group could not be optimized
W0017 a library jar's META-INF/onion/effect-table.txt is malformed and was ignored whole (reported at the jar and line)
W0018 a library jar's effect table names classes outside the jar; those entries were ignored
W0019 the result of an immutable builder method (Http.Request.header, ...) is discarded as a statement, so the call does nothing
W0020 an extension method's name and arity exactly match an existing member (own or inherited); the existing member always wins, so the extension method is never called
W0021 a method can break a history: the solver found a counterexample (a warning, since it may rest on an integer wrap-around the program never reaches)
W0022 the contract of a Shape was not checked: its value type cannot be sampled
W0023 the build did not run a contract predicate: its effects go beyond mutate (it prints, does I/O, or calls something unknown), or it did not finish within 10 seconds; also a Shape whose round-trip check (E0114) would run code with such an effect, or did not finish in time
W0024 a method writes a field that a history names, and no check settled whether the history still holds: the field is not an Int, the solver does not model the method body, the write is in a lambda, the proof needs a class invariant (nothing proves an invariant at compile time yet, so a constructor may break it), or the history is not of the form x >= old(x), x <= old(x), x == old(x). Nothing guarantees the history there
W0025 an override can break the contract it inherits: the solver found a counterexample (a warning, since it may rest on an integer wrap-around the program never reaches)
W0026 a contract clause is not enforced at run time by --contracts runtime, with the reason (a warning, so a clause that is not guarded is never silent)
W0027 the contract of a method is trusted, not verified (@Trusted): its body is not checked and callers rely on it; each use is listed
W0028 a method can break its ensures: the solver found values for which the body ends with the clause false

Every diagnostic code

The sections above explain the codes you are most likely to meet, with examples. This table lists every E and I code, so a code seen in a build log can always be looked up; see Warnings above for the W codes.

Code Meaning
I0000 internal compiler error — a bug in the compiler, not your program
E0000 type … is expected, but type … is used
E0001 operator … is not applicable for type …
E0002 variable not found
E0003 class not found
E0004 field ….… is not found
E0005 a method applicable for ….…(…) is not found
E0006 ambiguous method
E0007 duplicated local variable definition …
E0008 duplicated class definition …
E0009 duplicated field definition ….…
E0010 duplicated method definition ….…(…)
E0011 duplicated global variable definition …
E0012 duplicated function definition …(…)
E0013 method ….…(…) is not accessible from class …
E0014 field ….… is not accessible from class …
E0015 class … is not accessible from class …
E0016 inheritance relations which include … have cyclicity
E0018 class … has illegal inheritance: …
E0019 method ….… cannot be called
E0020 this method cannot return a value
E0021 a constructor applicable for …(…) is not found
E0022 ambiguous constructor
E0023 an interface is required, but type … is used
E0025 duplicated constructor definition …(…)
E0026 duplicated generated method ….…(…)
E0027 type … is not a boxable type
E0028 an lvalue is required
E0029 duplicated type parameter definition …
E0030 type … does not take type arguments
E0031 type … expects … type argument(s), but … is/are supplied
E0032 type argument … must be a reference type
E0033 method ….… does not take type arguments
E0034 method ….… expects … type argument(s), but … is/are supplied
E0035 Erased JVM signature collision: ….……
E0036 cannot assign to val …
E0037 class … must implement abstract method …(…) or be declared abstract
E0038 cannot instantiate abstract class …
E0039 method …(…) cannot override final method in …
E0040 cannot call method … on primitive type …
E0041 type … is not a valid method call target
E0042 non exhaustive pattern match
E0043 unknown parameter name: …
E0044 duplicate argument: …
E0045 positional argument after named argument is not allowed
E0046 wrong number of bindings in destructuring pattern
E0047 … is not a record type or does not exist
E0048 break is only allowed inside a loop
E0049 continue is only allowed inside a loop
E0050 current instance is not available in a static context
E0051 a return type is required for method …
E0052 lambda parameter … must specify a type
E0053 cyclic type alias detected: …
E0054 duplicate type alias: …
E0055 function … requires a body
E0057 value of type parameter … may be null and cannot be dereferenced directly
E0058 label … is not defined on any enclosing loop
E0059 invalid regular expression literal: …
E0060 the regex pattern has … capture group(s) but … binding(s) was/were given
E0061 record component … has type …, which cannot be derived from a … clause
E0062 record component … has type …, which derive! cannot serialize
E0063 unknown derive! marker …
E0066 raw type … is not allowed; supply type arguments (e.g
E0067 method … may reach the end of its body without returning a …
E0068 method …(…) is marked override but does not override any method in a base class or interface of …
E0069 local val … must be initialized at its declaration
E0070 value of type … may be null and cannot be dereferenced directly
E0071 … is a variable, not a type
E0072 abstract method … cannot have a body (the body would be silently ignored)
E0073 a Map (…) cannot be iterated directly by foreach
E0076 unknown shape format …
E0077 tool … performs … here (calling …) but does not declare it
E0078 tool … declares capability … but nothing in its body can perform it
E0079 tool … has an invalid capability …: …
E0081 tool parameter not cli convertible
E0082 duplicate tool name …
E0083 this catch clause for … can never be reached: an earlier catch clause for … already handles it
E0084 duplicated extension method …(…) on …
E0085 static method … must have a body
E0086 duplicated record component … in …
E0087 class … has a primary constructor, so every def this must delegate to it
E0088 constructor delegation in … never reaches a constructor that calls the superclass
E0089 a record / an enum cannot declare def this: … already has its canonical constructor
E0090 this is used in a constructor's delegation arguments before the object of … exists
E0091 … is a class, not a variable
E0092 cannot instantiate primitive type … with new
E0093 parameters … and … of … would both answer to the command-line flag --…
E0094 main parameter … has type … which cannot be read from an argument
E0095 main has a String[] parameter, …, that is not in a supported position
E0096 abstract method … cannot be private
E0097 instance … is already defined (at most one instance is allowed per (trait, type))
E0098 enum … mixes shared parameters with case cases
E0099 enum … cannot take type parameters
E0100 this case combines more than one type/destructuring/regex/binding pattern with ,
E0101 this lambda takes … parameter(s), but the expected function type … takes …
E0102 an extension block for … is already defined (combine the methods for the same type into one block)
E0103 foreach (a, b) in ... walks the entries of a Map, but this is … (use foreach p in ... { val (a, b) = p ... })
E0104 …(): … cannot override ….…(): … (when either return type is primitive, both must be the same type)
E0105 the … clause is a contract, and contracts are off (compile with --contracts check)
E0106 this contract calls …, which … (a contract may not do I/O or write memory)
E0107 old(...) is allowed only in an ensures or a history
E0108 this history is not a preorder: … is not both reflexive and transitive
E0109 this write can break the history … on …
E0110 an invariant or history names a field that holds a mutable object, or such a field is written through another object
E0111 a class with an invariant or history extends a Java class
E0112 this method breaks the history … when run from …
E0113 the closed predicate … is … when the build runs it
E0114 the Shape … breaks its round-trip contract
E0115 super.…(...) calls an abstract method of …

See also