Joa produces structured error messages. Depending on the error and available source information, diagnostics include:
- The error kind (Syntax, Type, Runtime, Name)
- A plain-language description of what went wrong
- A file reference with line and column numbers
- A source excerpt with a
^caret pointing at the exact position - A
💡 Hintsuggesting how to fix it, when one is supplied
Error Format
❌ <Kind> Error: <message>
--> <file>:<line>:<column>
|
N | <source line>
| ^
| <message repeated>
💡 Hint: <actionable fix>
Error Kinds
| Kind | When it occurs |
|---|---|
Syntax Error |
Unrecognized character, missing brace, malformed token |
Type Error |
Wrong type for operation (e.g. string CIDR, non-numeric math) |
Runtime Error |
Division by zero, out-of-bounds index, wrong argument count |
Name Error |
Reading or assigning an undeclared variable |
Examples
Missing opening brace:
if load > 90
print("High load")
// ❌ Syntax Error: Expected '{' to start a block, but found 'print'.
// --> monitor.jo:2:5
// |
// 2 | print("High load")
// | ^
// | Add a '{' here to open the block.
String used as subnet mask:
let zone = 192.168.0.0/16
let sub = zone.split("20")
// ❌ Type Error: subnet.split() requires an Integer CIDR prefix (e.g. split(28)).
// --> config.jo:2:21
// |
// 2 | let sub = zone.split("20")
// | ^
// 💡 Hint: Remove quotes if you used a string: split(28) not split("28").
Undefined variable:
print(user_count)
// ❌ Name Error: 'user_count' is not defined.
// --> app.jo:1:7
// |
// 1 | print(user_count)
// | ^
// 💡 Hint: Declare it first: let user_count = ...
Division by zero:
let ratio = total / active
// ❌ Runtime Error: Division by zero.
// --> calc.jo:1:17
// 💡 Hint: Ensure the divisor is not zero before dividing.