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.
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.
E0066 — Raw generic type not allowed¶
A generic type was used without type arguments. Onion forbids raw generic types; supply the type arguments explicitly.
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.
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.
E0003 — Class not found¶
A type name could not be resolved. Check spelling and imports.
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:
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).
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.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.
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).
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).
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.
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.
Iterate the entries with the destructuring form, or pick a view:
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.
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.
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.lengthwherex: String?). - Indexing —
b[i]/b[i] = v/b[i] += von a nullable array,List, orMap(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 anif/while/do-while/forcondition, or aselectguard'swhen. foreachcollection —foreach x: T in exprwhereexprhas nullable type.- Destructuring —
val (a, b) = exprwhereexpris a nullable record. - Array size —
new T[n]where a dimensionnhas nullable type (n: Int?). try-with-resources initializer —try (val r = res) { }wherereshas nullable type.throwoperand —throw exprwhereexprhas nullable type.selectscrutinee —select s { ... }whereshas nullable type (only when there's neither anelseclause nor an unconditional wildcard pattern -- either one already handles anullscrutinee correctly).- Range bound —
a..b/a..<bwhereaorbhas nullable type (these desugar to aRangeconstructor 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/vardeclaration's initializer, areturnvalue, 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). catchclause 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.
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.
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.
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.
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.
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.
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:
toStringfrom+and#{},hashCodefrom a map literal,equalsfrom==,getMessageof a thrown exception - the static initializer of each class the predicate uses, and of its superclasses
- for a parameter of a program class (
FooorFoo?): that class's constructors, static initializers andtoString, 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.
Fix: rename or remove one of the declarations.
E0009 — Duplicate field¶
The same field name is declared twice on a class.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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 … |