What does a specific EK9 error code mean?
← Debugging and Troubleshooting · Ref: Q248
Every EK9 compiler error has a unique code in the format EXXXXX (E followed by five digits). Use 'ek9 -h EXXXXX' to look up any error code for a detailed explanation.
LOOKING UP ERROR CODES
Run the following command to see a detailed explanation:
ek9 -h E50001
This works offline and shows what the error means, what causes it, and how to fix it.
ERROR CODE RANGES
Error codes are organised into ranges by category. A few examples from each (the meaning shown is the first line of 'ek9 -h <code>'):
E01xxx - Names, References and Excluded Keywords
E01010: A reference is missing its module qualifier ('::') E01020: The EK9 core module names (org.ek9.lang, org.ek9.math) are reserved E01030: A name matches an existing symbol of a different kind in scope E01072: 'return' does not exist in EK9
E02xxx - Duplicate Definitions
E02010: A property with this name already exists in the type hierarchy E02030: Two or more methods have the same signature
E04xxx - Type Constraints and Conversion
E04010: A constraint applied to a type that cannot be constrained E04020: A string interpolation value cannot be converted to a String
E05xxx - Type Hierarchy
E05020: Circular type hierarchy detected E05030: Type is not open for extension (closed by default) E05120: Method or operator must use the override keyword (it overrides a parent's)
E06xxx - Parameters and Arguments
E06260: A 'defines package' property has a value of the wrong kind E06280: Too many arguments E06290: Too few arguments E06330: Incompatible type arguments for a generic type
E07xxx - Operators and Methods
E07500: Operator must be pure but is not declared pure E07510: Operator cannot be pure (mutation operators) E07520: Must return Boolean E07550: Must return Integer E07570: Must return String E07580: Must return JSON E07620: The type has no such operator
E08xxx - Flow Analysis and DI
E08020: Variable used before it is initialised E08030: Optional, Result or Iterator accessed without checking it first E08050: Return variable not initialised on all paths E08055: Return initialised before a require (declare 'as Type?', assign after the require) E08190: Circular dependency injection detected
E11xxx - Code Quality
E11010: Cyclomatic complexity exceeds the threshold E11031: Non-descriptive variable name E11032: Variable name shadows a built-in operator keyword E11040: A component has too many injected fields
E50xxx - Resolution and Type Compatibility
E50001: Variable or identifier not resolved E50030: Incompatible types (one type used where a different one is expected) E50060: No method matches that name and those parameter types
COMMON FIRST ERRORS
The most common errors for new EK9 developers are:
- E50001: check the spelling and ensure references are correct
- E05030: mark the base type 'as open' if you intend to extend it
- E08020: initialise the variable before using it
- E06280/E06290: check the number of arguments
See Q247 for understanding error message format. See Q252 for verbose compilation modes. See Q238 for the complete operator set and enforcement rules. See Q290 for E11031 and E11032 naming errors. See Q291 for naming error troubleshooting. See Q311 for the complete quality checks catalog.
Example
defines module qa.debugging.errorcodelookup defines class Account name <- String() balance <- Float() Account() -> accountName as String initialBalance as Float require accountName? require initialBalance? require initialBalance >= 0.0 this.name :=: accountName this.balance :=: initialBalance deposit() -> amount as Float require amount? require amount > 0.0 balance += amount getBalance() as pure <- rtn as Float: balance operator $ as pure <- rtn as String: `Account(${name}, ${balance})` //The sameness is the account's identity (its name); == and <> are generated from it operator <=> as pure -> other as Account <- rtn as Integer: name <=> other.name operator #? as pure <- rtn as Integer: #? name override operator ? as pure <- rtn as Boolean: name? and balance? defines program ErrorCodeDemo() stdout <- Stdout() // Correctly constructed class with operators acc <- Account("Alice", 100.0) stdout.println(`Account: ${acc}`) acc.deposit(50.0) stdout.println(`After deposit: ${acc}`) stdout.println(`Balance: ${acc.getBalance()}`) // Correct comparison usage acc2 <- Account("Bob", 200.0) stdout.println(`Equal: ${acc == acc2}`) stdout.println(`Compare: ${acc <=> acc2}`)
Common mistakes
E50060 — Calling a method that does not exist on the type produces a resolution error. The Account class defines 'deposit' but not 'withdraw'. See ek9 -h E50060 for details.
Incorrect:
acc.withdraw(50.0)
Correct:
acc.deposit(50.0)
E08090 — If 'balance' is declared but never used in any expression or output, the compiler rejects it as unused. See ek9 -h E08090 for details.
Incorrect:
balance <- acc.getBalance()
Correct:
stdout.println(`Balance: ${acc.getBalance()}`)
Other ways to ask this
- How do I look up an EK9 error code?
- What are the EK9 error code ranges?
- How do I find what EXXXXX means in EK9?
Coming from another language?
Java: javac error codes are not standardised, IDEs provide error databases. Python: no error code system, SyntaxError and named exceptions. Rust: E0001-E0999 error codes with 'rustc --explain E0308'. Go: no standardised error codes, terse messages. C++: compiler-specific error codes (GCC, Clang, MSVC all different). Kotlin: no standardised error codes, IDE-centric. EK9: unified EXXXXX error codes across all phases, offline lookup with 'ek9 -h EXXXXX', organised by category ranges.
Keywords: E50001, explain, help, meaning, lookup, error-message, E08020, range, E50030, category, debug, resolve, EXXXXX, E05030, error, troubleshoot, code