Error Codes

OcaltQL surfaces errors two ways: standard HTTP status codes for the response itself, and a dedicated E-series code for the specific failure inside CATCH ERROR. See Error Reporting & Catching for the full CATCH ERROR mechanism.

HTTP Status Codes

Set directly with STATUS n, or implicitly by certain verbs. These govern the response itself, independent of any OcaltQL-specific error code.

Code Meaning Typical cause in OcaltQL
200OKDefault success status
201CreatedACCOUNT REGISTER succeeding
302Found (redirect)REDIRECT "url" AS "302"
401UnauthorizedInvalid ACCOUNT LOGIN credentials, failed ACCOUNT COMPARE
404Not FoundACCOUNT DELETE on a non-existent account, unresolved routes
409ConflictDuplicate email on ACCOUNT REGISTER/UPDATE EMAIL
429Too Many RequestsDaily query quota exceeded — see Quotas & Pricing
500Internal Server ErrorUncaught FATAL runtime error

OcaltQL Error Codes (E-Series)

Every value captured by CATCH ERROR SET ?err includes an ?err("code") field from this table, alongside ?err("message") and ?err("verb"). Codes are grouped by domain — the first digit identifies the category.

E1xxx — Authentication & Accounts

Code Meaning
E1001Invalid credentials on ACCOUNT LOGIN
E1002Email already registered on ACCOUNT REGISTER
E1003Account not found
E1004Session token invalid or expired
E1005New email already in use on ACCOUNT UPDATE EMAIL

E2xxx — Filesystem

Code Meaning
E2001File not found
E2002Path outside /root or /mounted
E2005Path is not under /root, /mounted or a bound /external

E3xxx — Database

Code Meaning
E3001Database does not exist
E3002Table does not exist
E3003UNIQUE constraint violated on insert/update
E3004REQUIRED column missing on insert, with no default
E3005Row not found for WHERE clause on an update/delete expecting one

E4xxx — Network & Fetch

Code Meaning
E4001FETCH/CURL connection failed or timed out
E4002Remote host returned a non-2xx status
E4003Invalid URL
E4004WEBHOOK RECEIVE rejected an unsigned or incorrectly-signed request

E5xxx — Runtime & Execution

Code Meaning
E5001Syntax error — script failed to parse
E5002Undefined operation referenced by RUN
E5003Type mismatch on a typed parameter (WITH ?x AS NUMBER REQUIRED)
E5004WebAssembly/SSH remote execution failed — see ?result("stderr")/?result("exit_code")

E6xxx — GeoIP & DNS

Code Meaning
E6001Invalid IP address supplied to GEOIP
E6002No GeoIP record for that IP — private, reserved, or absent from the database
E6003GeoIP database unavailable
E6004No visitor IP in context — the bare GEOIP forms require Site Mode
E6005Invalid domain name supplied to DNS
E6006Unknown DNS record type
E6007DNS resolution failed — no records, NXDOMAIN, or resolver unreachable

E7xxx — Custom Query

Code Meaning
E7001Query phrase word is empty — nothing to register it under
E7002A matched phrase runs out — a later word continues no registered path. A first word that matches nothing is a FATAL unrecognized verb instead, not this code
E7003Ambiguous phrase match — a SKIPPABLE node makes more than one path valid
E7004CASE must be "sensitive" or "insensitive"

E8xxx — Object Oriented Programming

Code Meaning
E8001No class of that name has been declared
E8002A class inherits in a circle, or its parent does not exist
E8003A REQUIRED property was not supplied at SPAWN
E8004A property value does not fit its declared type
E8005CALL ... ON was given something other than an instance
E8006The class has no method of that name

Uncatchable (FATAL) States

A small number of failures are deliberately not catchable by OR CATCH ERROR — they represent a genuine script-authoring mistake, not a runtime condition to recover from gracefully.

Cause Why it is FATAL
Indexing into a multivariable without COLLAPSE firstThe value has no single element to index — this is a script logic error, documented on Multivariables & Parallel Execution
A first word that is neither a verb nor a registered query phraseReported as Unrecognized verb near '…'. Custom phrases are resolved at runtime, but a word that names nothing at all is still a script-authoring mistake — see Custom Query Programming
WAIT FOR with no timeout, unresolved past 300 secondsThe hard execution ceiling — always specify a timeout on WAIT FOR to receive a catchable result instead

Handling Errors

Reading Every Error Field
FILE READ "/root/missing.txt" SET ?data OR CATCH ERROR SET ?err
AFTER IF ?err IS NOT NULL
OPEN
  EMIT ?err("code") & ": " & ?err("message") & " (verb: " & ?err("verb") & ")"
CLOSE