Error Reference

You hit an error β€” here's what it means, what causes it, and how to fix it. Search your message, or browse by category.

How to read a LOOK error

Every LOOK error tells you what went wrong and where:

Runtime Error: Undefined variable: $userr
  File: app.lk
  Line: 42

Parse/compile errors also give the column:

Parse Error: Unexpected token: ')'
  File: app.lk
  Line: 2, Column: 12
  • The kind β€” Parse Error happens *before* your code runs (syntax);

Runtime Error happens *while* it runs (bad value, missing file, failed connection).

  • The message β€” the specific problem. Everything below is organized by this text.
  • File: / Line: (and Column: for parse errors) β€” exactly where it happened.

Parse errors point at the offending token; runtime errors point at the line being executed.

Messages are matched by their leading text. Where a message ends with … or a value (Undefined variable: $x), look it up by the part before the value.

1. Syntax & parse errors (before your code runs)

These come from the parser/compiler. Your program never starts until they are fixed.

Unexpected token: '…'

Cause A token appears where the grammar doesn't allow it (a stray ), a missing operator, a keyword used as a name).

Fix Look at the token in the message and the one before it. Usually a missing , ; { or an extra bracket.

# βœ— triggers the error
if $age > 18 { }            # missing parentheses
# βœ“ fix
if ($age > 18) { }
Unexpected character: '…'

Cause A character that isn't part of LOOK (e.g. a smart-quote " pasted from a document, a stray backtick).

Fix Replace it with the ASCII equivalent (", ').

# βœ— triggers the error
$s = β€œhello”                # smart quotes from a document
# βœ“ fix
$s = "hello"
Expect ';'. (got '…')

Cause A statement wasn't terminated.

Fix Add ; β€” or check the previous line for an unclosed (/{ that makes the parser think the statement continues.

Unterminated string at line N / Unterminated raw string at line N

Cause A "…" (or raw string) opened but never closed on that line.

Fix Close the quote. For text with newlines/quotes inside, use a raw string.

# βœ— triggers the error
$s = "hello                 # quote never closed
# βœ“ fix
$s = "hello"
Invalid assignment target.

Cause The left side of = isn't assignable (e.g. foo() = 1, $a + $b = 2).

Fix Assign to a variable, array element, or property β€” not to an expression.

# βœ— triggers the error
count($a) = 5               # left side isn't assignable
# βœ“ fix
$n = 5
an expression is required after throw

Cause throw with nothing after it.

Fix throw "message" β€” throw needs a value.

# βœ— triggers the error
throw
# βœ“ fix
throw "Not found"
Expression nested too deep (max N) / Expression chain too long (max N) / Expression/block nested too deep

Cause A single expression or block nests far deeper than the limit (often machine-generated code, or a runaway a.b.c.d… chain). This limit prevents a parser stack overflow.

Fix Break the expression into intermediate variables / smaller statements.

# βœ— triggers the error
$x = a(b(c(d(e(f(g(h( ... )))))))) # too deep
# βœ“ fix
$g = g(h(...))
$x = a(b(c($g)))   # split into steps
Jump target too far

Cause A single function compiled to more than 64 KB of bytecode β€” a jump can't reach that far.

Fix Split the function into smaller functions.

# βœ— triggers the error
function huge() { /* 64KB+ of code */ }
# βœ“ fix
# split into smaller functions
function part1() { ... }
function part2() { ... }

2. Undefined names

LOOK is strict: reading a variable that was never assigned is an error, not a silent

null. This catches typos early.

Undefined variable: $name

Cause You read $name before it was ever assigned β€” almost always a typo ($userr vs $user) or a variable from another scope.

Fix Assign it first ($name = …), or fix the spelling. A function cannot see the caller's variables β€” pass them as arguments.

# βœ— triggers the error
print($usr)                 # typo β€” $usr was never set
# βœ“ fix
$user = "Ada"
print($user)
Undefined variable read (LOOK_WARN_UNDEF transition mode, returned null): $name

Cause Same as above, but you set LOOK_WARN_UNDEF=1, which downgrades the error to a warning and returns null.

Fix Only a migration aid. Assign the variable; unset LOOK_WARN_UNDEF to get strict errors back.

# βœ— triggers the error
print($usr)                 # typo β€” $usr was never set
# βœ“ fix
$user = "Ada"
print($user)
Undefined function: name

Cause You called a function that isn't defined (typo, or you forgot to use its module/package).

Fix Check the spelling; add use <module> or use "pkg/<name>" if it lives in a module/package.

# βœ— triggers the error
echo("hi")                  # echo is not a LOOK function
# βœ“ fix
print("hi")
Built-in '<name>' unavailable (not linked)

Cause A built-in exists in this binary's name table but isn't wired into the running engine (rare; e.g. a CLI-only path hitting a web-only built-in).

Fix Use the documented built-in for your context; report it if a documented function triggers this.

3. Types, arithmetic & indexing

Arithmetic on a non-numeric value (null/array/object)

Cause You used + - * / on null, an array, or an object.

Fix Convert first (int(), float()), or check the value isn't null before the math.

# βœ— triggers the error
$total = $row + 5           # $row is an array / null
# βœ“ fix
$total = ($row["qty"] ?? 0) + 5
Arithmetic on an empty string

Cause Math on "".

Fix Guard empty input, or default it ($n = $s == "" ? 0 : int($s)).

# βœ— triggers the error
$n = $s + 1                 # $s is ""
# βœ“ fix
$n = ($s == "" ? 0 : int($s)) + 1
Arithmetic on a string that cannot be converted to a number: '…'

Cause The string isn't numeric ("12abc"). LOOK does not silently truncate.

Fix Validate with validator::integer/numeric, or clean the string before converting.

# βœ— triggers the error
$n = int("12abc")           # not a full number
# βœ“ fix
if (validator::integer($s)) { $n = int($s) }
Arithmetic on a numeric string exceeding the int64 limit (bignum/ID): '…'

Cause A numeric string is larger than a 64-bit integer (often a giant ID).

Fix Keep it as a string β€” don't do arithmetic on it. LOOK compares such IDs exactly as strings.

# βœ— triggers the error
$next = $big_id + 1         # 20-digit id > int64
# βœ“ fix
# keep large ids as strings β€” compare, don't do math
if ($a_id == $b_id) { ... }
Division by zero / Modulo by zero

Cause The right operand of / or % was 0.

Fix Check the divisor before dividing.

# βœ— triggers the error
$avg = $sum / $count
# βœ“ fix
$avg = $count == 0 ? 0 : $sum / $count
Index operator requires an array

Cause You used x[i] on something that isn't an array/object.

Fix Make sure x is an array; check for null first.

# βœ— triggers the error
$name = $user["name"]       # $user is null
# βœ“ fix
if (is_array($user)) { $name = $user["name"] }
Array index out of bounds / Array index …

Cause arr[i] with i past the end (or negative).

Fix Check count(arr) before indexing; array indexes are 0-based.

# βœ— triggers the error
$first = $rows[0]           # $rows may be empty
# βœ“ fix
if (count($rows) > 0) { $first = $rows[0] }
foreach requires an array

Cause foreach/for … as over a non-array (often null from a lookup that missed).

Fix Ensure the value is an array; default to [] when a lookup can miss.

# βœ— triggers the error
foreach ($rows as $r) { }   # $rows is null
# βœ“ fix
foreach ($rows ?? [] as $r) { }
++/-- requires a variable

Cause ++/-- applied to something that isn't a variable (e.g. ++5, ++foo()).

Fix Apply it to a variable: $i++.

# βœ— triggers the error
++count($arr)               # not a variable
# βœ“ fix
$i = count($arr)
$i++

4. Function arguments (built-ins)

Built-ins validate their arguments and throw a message of the shape

name() requires …, name() β€” expects …, or … must be a function. The message names

the exact function and what it wanted. General fixes:

  • … requires X β€” you passed too few arguments (or the wrong kind). Pass the listed arguments.
  • … β€” expects (a, b [, c]) β€” brackets mean optional. Provide at least the non-bracketed ones.
  • … must be a function β€” a callback argument got a value instead of a function(){…}.
  • … must be an array / must be a channel / must be a websocket β€” the argument is the wrong type; check what you passed.

Representative examples (same pattern applies across array::, string::, math::,

date::, crypto::, jobs::, queue::, ws::, sse::):

array::map() requires array and callback

Fix array::map($arr, function($x){ … }) β€” pass both.

# βœ— triggers the error
array::map($arr)            # missing callback
# βœ“ fix
array::map($arr, fn($x) => $x * 2)
array::chunk() size must be positive

Fix The size argument must be > 0.

# βœ— triggers the error
array::chunk($arr, 0)       # size must be > 0
# βœ“ fix
array::chunk($arr, 2)
array::zip() all arguments must be arrays

Fix Every argument to zip must be an array.

# βœ— triggers the error
array::zip($a, "x")         # every arg must be an array
# βœ“ fix
array::zip($a, $b)
math::max() expects 2+ arguments or 1 array

Fix Call math::max(a, b, …) or math::max($arr).

# βœ— triggers the error
math::max()                 # needs values
# βœ“ fix
math::max(3, 7, 2)   # or: math::max($arr)
math::sqrt: square root of a negative number is undefined

Fix Guard against negative input.

# βœ— triggers the error
math::sqrt($n)              # $n may be negative
# βœ“ fix
if ($n >= 0) { math::sqrt($n) }
date::add() requires (date, amount, unit)

Fix Pass all three; unit is "day", "hour", …

# βœ— triggers the error
date::add($d, 1)            # unit missing
# βœ“ fix
date::add($d, 1, "day")
date::parse(): invalid date β€” '…'

Fix The string didn't match the given format; check the format argument.

# βœ— triggers the error
date::parse("2026/13/40", $fmt)  # doesn't match
# βœ“ fix
date::parse("2026-08-17", "Y-m-d")
jobs::worker() β€” second argument must be a function

Fix Pass a handler function($job){ … }.

# βœ— triggers the error
jobs::worker("mail", $handler)   # not a function
# βœ“ fix
jobs::worker("mail", fn($job) => send($job))
string::format() requires format string

Fix The first argument must be the format string.

# βœ— triggers the error
string::format($name)       # format string first
# βœ“ fix
string::format("Hi %s", $name)

5. Input validation (validator::)

validator::check($data, $rules) returns field errors; individual rules throw these when a

value fails. <field> is your field name.

<field> is required

Meaning Missing or empty value.

Fix Provide the field. (An empty value only fails required; other rules pass on empty.)

<field> must be a number / must be an integer

Meaning numeric / integer rule failed β€” the value wasn't a full number ("12abc" is rejected, not truncated).

Fix Send a clean numeric value.

<field> must be at least N / must be at most N

Meaning min:N / max:N failed (length for strings, value for numbers).

Fix Adjust the input to the allowed range.

See the rule table in the main docs (required, email, integer, numeric, min:N,

max:N, in:a,b,c).

6. Database (db::)

Your API-usage errors:

db::connect() requires DSN string

Cause Called connect() with no DSN.

Fix db::connect("mysql://user:pass@host/db").

# βœ— triggers the error
db::connect()
# βœ“ fix
$conn = db::connect("mysql://root:@127.0.0.1/app")
db: invalid DSN format / db::connect() unsupported DSN scheme: …

Cause Malformed DSN, or a scheme other than mysql/postgresql/sqlite.

Fix Use a supported scheme and the scheme://user:pass@host:port/name shape.

# βœ— triggers the error
db::connect("root@localhost/app")   # no scheme
# βœ“ fix
db::connect("mysql://root:@localhost/app")
db::query() requires connection and SQL (and exec/begin/commit/… variants)

Cause You didn't pass the connection handle (and SQL).

Fix Pass the handle from db::connect() as the first argument.

# βœ— triggers the error
db::query("SELECT ...")     # missing connection
# βœ“ fix
db::query($conn, "SELECT ...", [])
db: connection not found / db: invalid connection handle

Cause The handle is stale/closed or from a different worker.

Fix Reconnect; don't share a handle across requests β€” open per request or use the pool.

db: parameter count mismatch β€” SQL …

Cause The number of ? placeholders β‰  the number of bound values.

Fix Match placeholders to the values array exactly.

# βœ— triggers the error
db::query($c, "... id=? AND a=?", [$id])
# βœ“ fix
db::query($c, "... id=? AND a=?", [$id, $a])
db: cannot bind NaN/Infinity float as a parameter

Cause You tried to bind NaN/Infinity.

Fix Validate/clean the number before binding.

db: query error … / db: server error …

Cause The database rejected the SQL (syntax, constraint, permission).

Fix Read the server's message after the colon; fix the SQL or the data.

Connection / network:

db: cannot resolve host: …

Cause DNS lookup failed.

Fix Check the hostname in the DSN.

db: cannot connect to … / db: connection timeout to …

Cause The server is down, firewalled, or the port is wrong.

Fix Verify host/port and that the DB accepts your IP.

db: connection lost / db: connection lost and reconnect failed after …

Cause The server dropped the connection and auto-reconnect failed.

Fix Check DB stability / timeouts; retry the operation.

db … TLS (…s://) is not supported in this build …

Cause You asked for TLS (mysqls://, postgresqls://, rediss://) but this binary was built without it.

Fix Use a TLS-enabled build, or connect over a trusted/loopback network.

db postgres: malformed DataRow β€” … / db mysql: column count limit exceeded (malicious server?)

Cause The server sent a wire response LOOK couldn't trust.

Fix Almost always a broken/incompatible or hostile server; verify you're talking to a real MySQL/Postgres.

7. Files & uploads (file::)

File access is sandboxed to a root directory (LOOK_FILE_ROOT); paths can't escape it.

file: access denied (path outside LOOK_FILE_ROOT): …

Cause The path resolved outside the sandbox root (often ../ traversal or an absolute path).

Fix Use a path inside the root; set LOOK_FILE_ROOT to the directory you intend to serve.

# βœ— triggers the error
file::read("../../etc/passwd")   # escapes the root
# βœ“ fix
file::read("config/app.json")   # inside LOOK_FILE_ROOT
file: invalid path: …

Cause The path is malformed.

Fix Use a plain relative path like config/app.json.

file::read(): cannot open: … (and put/append)

Cause The file doesn't exist or isn't readable/writable.

Fix Check the path and permissions; create the file/dir first for writes.

# βœ— triggers the error
file::read("missing.txt")   # not there
# βœ“ fix
if (file::exists($p)) { file::read($p) }
file::read() requires path (and other requires)

Cause Missing argument.

Fix Pass the path (and content for put/append).

# βœ— triggers the error
file::read()                # path required
# βœ“ fix
file::read("config/app.json")
Uploaded file exceeds max_size limit (…)

Cause An upload is bigger than the allowed size.

Fix Raise the max_size option, or reject large files client-side.

# βœ— triggers the error
file::store($f)             # over the size cap
# βœ“ fix
file::store($f, "img", ["max_size" => 5242880])
File type not allowed: …

Cause The upload's type isn't in your allow-list.

Fix Add the type to the allow-list, or block it intentionally.

# βœ— triggers the error
file::store($f)             # type not in the allow-list
# βœ“ fix
file::store($f, "docs", ["allowed" => ["pdf", "png"]])
SVG upload requires allow_svg: true option

Cause SVG is blocked by default (it can carry scripts).

Fix Only set allow_svg: true if you sanitize/trust the SVG.

# βœ— triggers the error
file::store($upload)        # SVG blocked by default
# βœ“ fix
file::store($upload, "img", ["allow_svg" => true])
file::store(): upload dir cannot be under web root β€” set UPLOAD_DIR to a path outside web root

Cause Saving uploads inside the web root would make them executable/served.

Fix Point UPLOAD_DIR outside the public web root.

# βœ— triggers the error
file::store($f, "uploads")   # folder under the web root
# βœ“ fix
# point UPLOAD_DIR outside the public web root, e.g. /var/look-uploads
file::store(): subdir must be a simple name, not a path

Cause The subdir argument contained path separators.

Fix Use a single folder name (no /, no ..).

# βœ— triggers the error
file::store($f, "a/b/c")    # separators not allowed
# βœ“ fix
file::store($f, "avatars")

8. HTTP client (http::)

http::get() β€” URL required (and post/put/delete/patch)

Cause No URL (or body) passed.

Fix Pass the URL; post/put/patch also need a body.

# βœ— triggers the error
http::get()                 # url required
# βœ“ fix
http::get("https://api.example.com/users")
http:: Unsupported URL scheme: …

Cause Not http/https.

Fix Use an http(s):// URL.

# βœ— triggers the error
http::get("ftp://host/f")
# βœ“ fix
http::get("https://host/f")
http:: Invalid IPv6 URL (missing closing ']'): …

Cause An IPv6 host wasn't bracketed.

Fix Wrap the address: http://[::1]:8080/.

# βœ— triggers the error
http::get("http://::1:8080/")   # unbracketed
# βœ“ fix
http::get("http://[::1]:8080/")
http::stream() β€” the 5th arg (callback) must be a function

Cause The streaming callback wasn't a function.

Fix Pass function($chunk){ … } as the 5th argument.

# βœ— triggers the error
http::stream($url, "GET", [], "", $cb)   # $cb not a function
# βœ“ fix
http::stream($url, "GET", [], "", fn($chunk) => print($chunk))

9. Templates (template::)

Template file not found: …

Cause The view file path doesn't exist (relative to the views directory).

Fix Check the path/filename passed to template::render().

# βœ— triggers the error
template::render("page.html")   # wrong path
# βœ“ fix
template::render("pages/page.html", $data)
Template parse error in '…'

Cause The template syntax is invalid ({#if} without {/if}, bad tag).

Fix Fix the tag; every {#…} block needs its closing tag.

# βœ— triggers the error
{#each $items as $i} ...        # no closing tag
# βœ“ fix
{#each $items as $i} ... {/each}
Template security error: escape outside the allowed directory blocked: …

Cause A {#extends}/{#include} path pointed outside the views directory.

Fix Reference templates by relative name inside the views root only.

# βœ— triggers the error
{#include "../secret.html"}   # escapes the views dir
# βœ“ fix
{#include "partials/header.html"}
template::render() expects 1 or 2 arguments: (file_path [, $data])

Cause Wrong argument count/type.

Fix template::render("page.html", $data).

# βœ— triggers the error
template::render()
# βœ“ fix
template::render("page.html", $data)

10. Crypto (crypto::)

crypto::sha256() β€” data required (and hmac, base64, hex, …)

Cause Missing argument.

Fix Pass the data (and key for hmac).

# βœ— triggers the error
crypto::sha256()            # data required
# βœ“ fix
crypto::sha256($payload)
crypto::random_bytes() β€” must be 1-4096 / random_string() β€” must be 1-4096

Cause Requested length outside 1–4096.

Fix Ask for a length in range; call repeatedly if you need more.

# βœ— triggers the error
crypto::random_bytes(9000)  # must be 1-4096
# βœ“ fix
crypto::random_bytes(32)
crypto::rs256_sign() β€” RSA key required (EC/incompatible key rejected)

Cause The PEM was not an RSA private key.

Fix Provide a PKCS#8 RSA private key.

# βœ— triggers the error
crypto::rs256_sign($data, $ec_pem)   # EC key rejected
# βœ“ fix
# use a PKCS#8 RSA private key
crypto::rs256_sign($data, $rsa_pem)
crypto::rs256_sign() β€” PEM key parse error / RSA key import error (PKCS#8 PEM required)

Cause The PEM couldn't be parsed.

Fix Check the key is valid PKCS#8 PEM, unencrypted, with proper -----BEGIN… lines.

# βœ— triggers the error
crypto::rs256_sign($data, $ec_pem)   # EC key rejected
# βœ“ fix
# use a PKCS#8 RSA private key
crypto::rs256_sign($data, $rsa_pem)
crypto::rs256_verify() β€” data, sig and PEM public key required

Cause Missing one of the three arguments.

Fix Pass data, signature, and the PEM public key.

# βœ— triggers the error
crypto::rs256_verify($data, $sig)   # public key missing
# βœ“ fix
crypto::rs256_verify($data, $sig, $public_pem)

11. Sessions, cookies & auth

session: could not obtain secure randomness (…)

Cause The OS CSPRNG was unavailable when creating a session ID.

Fix System-level; ensure /dev/urandom (or the Windows CSPRNG) is available.

auth::hash() requires password

Cause No password passed.

Fix Pass the plaintext password to hash.

# βœ— triggers the error
auth::hash()                # password required
# βœ“ fix
$hash = auth::hash($password)
auth: could not read enough random bytes

Cause CSPRNG failure while hashing.

Fix System-level randomness problem; check the environment.

12. Realtime β€” WebSocket, SSE, channels

ws::send() first argument must be a websocket (and on/close, same for sse::)

Cause The first argument wasn't the connection handle.

Fix Pass the connection object you got in the handler.

# βœ— triggers the error
ws::send($msg)              # first arg must be the socket
# βœ“ fix
ws::send($ws, $msg)
WebSocket connection limit exceeded (…) / SSE connection limit exceeded (…)

Cause Too many concurrent connections.

Fix Raise the configured limit, or shed/close idle connections.

ws::decode_frame: frame rejected (incomplete or oversized)

Cause A malformed/oversized WebSocket frame.

Fix Usually a misbehaving client; nothing to fix server-side.

send on closed channel

Cause You sent to a channel after it was closed.

Fix Don't send after close(); coordinate producers/consumers.

# βœ— triggers the error
close($ch)
send($ch, $v)               # channel already closed
# βœ“ fix
send($ch, $v)
close($ch)                   # send first, then close
channel send/receive timeout (possible deadlock; LOOK_CHANNEL_TIMEOUT_MS)

Cause A channel op blocked past the timeout β€” often no counterpart is reading/writing (deadlock).

Fix Ensure a receiver exists for every sender; adjust LOOK_CHANNEL_TIMEOUT_MS for genuinely slow work.

channel: capacity cannot be negative

Cause channel(-1).

Fix Use a capacity >= 0.

# βœ— triggers the error
$ch = channel(-1)
# βœ“ fix
$ch = channel(0)   # unbuffered, or a positive size
Channels/go{} are an experimental, opt-in feature β€” see the docs before relying on them.

13. Jobs & queues (jobs::, queue::)

jobs::push() β€” expects (queue, payload [, max_retries [, delay]])

Cause Wrong arguments.

Fix Pass at least the queue name and payload.

# βœ— triggers the error
jobs::push("mail")          # payload required
# βœ“ fix
jobs::push("mail", ["to" => $email])
jobs::run() β€” register a handler first with jobs::worker()

Cause You ran the worker loop with no handler registered.

Fix Call jobs::worker("queue", function($job){ … }) first.

# βœ— triggers the error
jobs::run()                 # no handler registered
# βœ“ fix
jobs::worker("mail", fn($job) => send($job))
jobs::run()
jobs:: could not open DB (…) / jobs:: schema error: …

Cause The job store (SQLite) couldn't be opened/initialized.

Fix Check the job DB path and write permissions.

queue::push() β€” expects (name, value) (and pop/peek/size/clear β€” expects name)

Cause Missing arguments.

Fix Pass the queue name (and value for push).

# βœ— triggers the error
queue::push("mail")         # value required
# βœ“ fix
queue::push("mail", $job)

14. Mail (mail::)

mail:: β€” MAIL_API_KEY env variable is missing

Cause The provider API key isn't set.

Fix Set MAIL_API_KEY in the environment.

mail:: β€” MAIL_FROM env variable is missing (or specify the from parameter)

Cause No sender address.

Fix Set MAIL_FROM, or pass from to mail::send().

mail:: β€” MAIL_DOMAIN is required for Mailgun

Cause Mailgun needs a domain.

Fix Set MAIL_DOMAIN.

mail:: β€” Unknown provider: …

Cause MAIL_PROVIDER isn't a supported provider.

Fix Use a supported provider name.

mail::send() β€” expects (to, subject [, text [, html [, from]]])

Cause Wrong arguments.

Fix Pass at least to and subject.

# βœ— triggers the error
mail::send($to)             # subject required
# βœ“ fix
mail::send($to, "Welcome", $body)

15. Cache & Redis

cache::set() β€” expects (key, value [, ttl]) (and get/has/delete β€” expects key)

Cause Missing arguments.

Fix Pass the key (and value for set).

# βœ— triggers the error
cache::set("k")             # value required
# βœ“ fix
cache::set("k", $value, 300)   # ttl seconds
Redis: cannot connect to … / Redis: cannot resolve …

Cause Redis host/port unreachable.

Fix Check the Redis address and that it's running.

Redis AUTH failed

Cause Wrong Redis password.

Fix Fix the credentials in the connection URL.

Redis TLS (rediss://) is not supported in this build …

Cause TLS Redis requested on a non-TLS build.

Fix Use a TLS build or a plain redis:// connection on a trusted network.

Redis: … limit exceeded (…)

Cause A response exceeded a safety limit (bulk/array/line).

Fix Usually a huge value or a misbehaving server; fetch smaller values.

16. Regular expressions (string::regex*)

Regex has built-in ReDoS and size protections.

string::regex: execution timeout (ReDoS protection β€” pattern too complex)

Cause The pattern took too long on this input (catastrophic backtracking).

Fix Simplify the pattern; avoid nested quantifiers like (a+)+.

# βœ— triggers the error
string::regex_match($s, "(a+)+$")   # catastrophic backtracking
# βœ“ fix
string::regex_match($s, "a+$")
string::regex: concurrent regex limit exceeded (max 8)

Cause More than 8 regex operations ran at once.

Fix Reduce concurrent regex work; reuse results.

string::regex_match(): input too long (max 65536) / pattern too long (max 2048)

Cause Input/pattern exceeds the size cap.

Fix Trim the input, or pre-filter before matching.

# βœ— triggers the error
string::regex_match($huge, $p)
# βœ“ fix
string::regex_match(string::substr($huge, 0, 65536), $p)

17. Modules & packages (use, lk module/install)

Only github.com is supported at the moment.

Cause An install source other than github.com.

Fix Use github.com/user/repo.

# βœ— triggers the error
lk install gitlab.com/user/repo
# βœ“ fix
lk install github.com/user/repo
Invalid package (user/repo required): …

Cause The path isn't user/repo.

Fix Give the full github.com/user/repo[/subdir].

# βœ— triggers the error
lk install github.com/repo
# βœ“ fix
lk install github.com/user/repo
Invalid package <what> (path-escape character): …

Cause The user/subdir contained .. or path separators (traversal attempt).

Fix Use plain names β€” no .., no slashes inside a component.

# βœ— triggers the error
lk install github.com/user/../repo
# βœ“ fix
lk install github.com/user/repo
'…' folder not found in the repo. / Official module not found.

Cause The named module/subdir doesn't exist in the repo.

Fix Check the module name and the repo path.

Could not open module file: … / Unknown module: '…'

Cause A used file/module can't be found or loaded.

Fix Check the path in use; run lk module install … for external modules.

# βœ— triggers the error
use "helpers.lk"           # wrong path
# βœ“ fix
use "lib/helpers.lk"   # or: lk module install github.com/user/repo

18. System / infrastructure errors (rare)

These come from the OS, not your code β€” you usually can't fix them in .lk:

bind() failed on port …, listen() failed, socket() failed, epoll_create1 failed,

eventfd failed, CreateIoCompletionPort failed, fiber: … failed,

… CSPRNG unavailable (/dev/urandom | BCryptGenRandom).

Typical causes: the port is already in use (bind() failed), the process hit a

file-descriptor / memory limit, or the OS randomness source is unavailable in a

locked-down container. Free the port, raise ulimit, or fix the container's /dev/urandom.

Still stuck?

  • Re-read the message's leading text and find its row above β€” the value after it is your specific input.
  • Check the file:line and the line just before it.
  • For behavior questions (what a function expects), see the main API docs.
  • If a documented function produces unavailable (not linked) or a Compile Error on

valid code, that's a bug worth reporting.