Table of Contents

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:

// 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:

  1. You called .charAt() and compared the result with a string instead of an int
  2. You used a pointer after freeing it (in unsafe code)
  3. 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:

// 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

  1. Read the error message carefully. Nyx error messages include the line number and a description of the problem.
  1. Compile with IR output. Use make compile FILE=prog.nx to see the generated LLVM IR. Look for the function where the error occurs.
  1. Simplify. If a complex program fails, extract the failing part into a minimal test file.
  1. Check types. Most errors come from type mismatches. Remember:
  1. Check imports. If a function is "undefined," you probably forgot to import its module.

← Back to Table of Contents

← Previous: Appendix B: Standard library modules Next: Appendix D: Glossary →