Appendix C: Common error messages
This appendix lists the most common errors you will encounter when programming in Nyx, along with their causes and fixes.
Type errors
"Type mismatch: expected X, got Y"
You are using a value of the wrong type where a specific type is expected.
// Error: Type mismatch: expected int, got String let x: int = "hello" // Fix: use the correct type let x: String = "hello" // Or convert: let x: int = string_to_int("42")
"Cannot assign to immutable variable"
You declared a variable with let (immutable) and tried to change it.
// Error: Cannot assign to immutable variable 'x' let x: int = 10 x = 20 // Fix: use 'var' for mutable variables var x: int = 10 x = 20
"Undefined variable: X"
You are using a variable that has not been declared in the current scope.
// Error: Undefined variable: count print(int_to_string(count)) // Fix: declare the variable first var count: int = 0 print(int_to_string(count))
"Undefined function: X"
You are calling a function that does not exist or has not been imported.
// Error: Undefined function: json_parse let data: Map = json_parse(text) // Fix: import the module that defines the function import "std/json" let data: Map = json_parse(text)
Syntax errors
"Expected '{' after ..."
Nyx requires curly braces for all blocks — no single-line shortcuts.
// Error: Expected '{' after if condition if x > 0 print("positive") // Fix: add braces if x > 0 { print("positive") }
"Expected type annotation"
Function parameters require explicit types.
// Error: Expected type annotation fn add(a, b) { return a + b } // Fix: add type annotations fn add(a: int, b: int) -> int { return a + b }
"Unexpected token"
The parser found something it did not expect. Common causes:
- Missing closing brace
} - Missing comma in struct fields
- Using a keyword as a variable name
// Error: Unexpected token struct Point { x: int y: int } // Fix: add commas between fields struct Point { x: int, y: int }
Runtime errors
"Index out of bounds"
You are accessing an array with an index that is too large or negative.
let arr: Array = [1, 2, 3] // Runtime error: Index out of bounds (index 5, length 3) let x: int = arr[5] // Fix: check the length first if index < arr.length() { let x: int = arr[index] }
"Division by zero"
// Runtime error: Division by zero let result: int = 10 / 0 // Fix: check the divisor if divisor != 0 { let result: int = 10 / divisor }
"Key not found"
Accessing a Map key that does not exist.
let m: Map = Map.new() // Runtime error: key not found let v: String = m.get("missing") // Fix: check first with .contains() if m.contains("missing") { let v: String = m.get("missing") }
"Null pointer / segmentation fault"
This usually means:
- You called
.charAt()and compared the result with a string instead of an int - You used a pointer after freeing it (in unsafe code)
- You accessed a struct field on a null reference
// Bug: charAt returns int (ASCII value), NOT a string let ch: int = name.charAt(0) if ch == "A" { } // WRONG — comparing int with String → crash // Fix: compare with ASCII value if ch == 65 { } // 65 is ASCII for 'A'
Import errors
"Module not found: X"
The compiler cannot find the module you are importing.
// Error: Module not found: utils import "utils" // Fix: check the path. Local files need correct relative path: import "src/utils" // Standard library uses std/ prefix: import "std/json"
"Circular import detected"
Two modules import each other, creating a cycle.
// a.nx: import "b" // b.nx: import "a" ← circular! // Fix: restructure. Extract shared code into a third module: // common.nx: shared definitions // a.nx: import "common" // b.nx: import "common"
Match errors
"Non-exhaustive match"
Your match does not cover all possible cases.
enum Color { Red, Green, Blue } // Error: Non-exhaustive match — missing: Blue match color { Red => print("red"), Green => print("green") } // Fix: add the missing case, or use a wildcard match color { Red => print("red"), Green => print("green"), _ => print("other") }
Struct errors
"Unknown field: X"
You are accessing a field that does not exist on the struct.
struct Point { x: int, y: int } let p: Point = Point { x: 1, y: 2 } // Error: Unknown field: z print(int_to_string(p.z)) // Fix: use a field that exists print(int_to_string(p.x))
"Missing field: X in struct initializer"
You forgot to initialize a required field.
struct Point { x: int, y: int } // Error: Missing field: y let p: Point = Point { x: 1 } // Fix: provide all fields let p: Point = Point { x: 1, y: 2 }
Concurrency errors
"Channel closed" / negative return from channel_recv
The channel has been closed or is invalid.
let ch: Map = channel_new(4) // If channel_recv returns a negative value, the channel is closed let val: int = channel_recv(ch) if val < 0 { print("Channel closed") }
Deadlock (program hangs)
Common causes:
- Sending to a full channel with no receivers
- Receiving from an empty channel with no senders
- Two threads waiting for each other
// Deadlock: main sends but nobody receives let ch: Map = channel_new(1) channel_send(ch, 1) channel_send(ch, 2) // blocks — channel full, no receiver // Fix: spawn a receiver, or increase channel capacity
Codegen / LLVM errors
"Function handler crashes" (known issue)
Do not use handler as a function name — it conflicts with internal codegen.
// CRASHES the compiler fn handler(req: Array) -> String { ... } // Fix: use a different name fn request_handler(req: Array) -> String { ... } fn on_request(req: Array) -> String { ... }
General debugging tips
- Read the error message carefully. Nyx error messages include the line number and a description of the problem.
- Compile with IR output. Use
make compile FILE=prog.nxto see the generated LLVM IR. Look for the function where the error occurs.
- Simplify. If a complex program fails, extract the failing part into a minimal test file.
- Check types. Most errors come from type mismatches. Remember:
.charAt()returnsint, notStringchannel_new()returnsMaptype- Array indexing returns a generic value — cast if needed
- Check imports. If a function is "undefined," you probably forgot to import its module.