Skip to main content

Error reference

Every LoraDB error carries a stable LORA_* code drawn from a single catalog. The code is part of the public API and never changes between releases; the human-readable message is allowed to evolve. Bindings, the HTTP server, and integration tests should match on the code, never on the message.

Codes

Client errors (caller's fault)

CodeWhen you'll see it
LORA_PARSECypher syntax could not be parsed.
LORA_SEMANTICUnknown variable, label, function, or type mismatch.
LORA_INVALID_PARAMSA parameter value couldn't be coerced into a Lora value.
LORA_READ_ONLYA mutating statement was issued in a read-only context.
LORA_NOT_FOUNDA named entity (database, label, key) does not exist.
LORA_CONSTRAINTA precondition failed (e.g. DELETE on a node with relationships — use DETACH DELETE).
LORA_INVALID_VECTORA vector value failed dimension or coordinate-type validation.
LORA_TIMEOUTThe query exceeded its cooperative deadline.
LORA_DATABASE_NAMEA logical database name violates the portable-path rules.
LORA_CONFIGA CLI flag or configuration value is invalid.

Server errors (engine's fault)

CodeWhen you'll see it
LORA_IOAn I/O failure outside the WAL / snapshot subsystems.
LORA_WAL_CORRUPTIONA WAL record was truncated, mis-CRC'd, or otherwise unreadable.
LORA_WAL_POISONEDThe WAL is poisoned and no longer accepts durable writes.
LORA_SNAPSHOT_CODECSnapshot bad magic, version, or checksum.
LORA_SNAPSHOT_CRYPTOSnapshot encryption / decryption / KDF failure.
LORA_INTERNALThe engine could not classify the failure.

Binding-side codes

CodeWhen you'll see it
LORA_PANICA Rust panic was caught at a binding boundary. The process keeps running; the call returns this code instead.

HTTP transport

The Axum server returns errors as JSON:

{
"error": {
"code": "LORA_PARSE",
"message": "parse error at 0..10: expected statement",
"category": "client"
}
}

category is "client" (4xx) or "server" (5xx). The HTTP status code follows the category, with two refinements: LORA_TIMEOUT408 Request Timeout, LORA_NOT_FOUND404 Not Found. Everything else in the client category is 400 Bad Request; everything in the server category is 500 Internal Server Error.

Examples per language

Rust

use lora_database::{Database, LoraError, LoraErrorCode};

let db = Database::in_memory();
match db.execute("NOT CYPHER", None) {
Ok(_) => {}
Err(e) => {
let lora = LoraError::from_anyhow(e);
if lora.code() == LoraErrorCode::Parse {
eprintln!("syntax: {}", lora.message());
}
}
}

Node.js / TypeScript

import { LoraError } from "@loradb/loradb";

try {
await db.execute("NOT CYPHER");
} catch (err) {
if (err instanceof LoraError) {
if (err.engineCode === "LORA_PARSE") console.error("syntax:", err.message);
if (!err.isClient()) reportToMonitoring(err);
}
}

err.code continues to be the legacy umbrella code ("LORA_ERROR" or "INVALID_PARAMS") for backwards compatibility; err.engineCode is the precise wire string from the catalog above.

Python

from lora_python import LoraQueryError

try:
db.execute("NOT CYPHER")
except LoraQueryError as e:
code, _, message = str(e).partition(": ")
if code == "LORA_PARSE":
print(f"syntax: {message}")

Go

import "github.com/lora-db/lora/crates/bindings/lora-go"

if _, err := db.Execute("NOT CYPHER", nil); err != nil {
var le *lora.LoraError
if errors.As(err, &le) && le.Code == lora.CodeParse {
fmt.Println("syntax:", le.Message)
}
}

Ruby

begin
db.execute("NOT CYPHER")
rescue LoraRuby::QueryError => e
code, _, message = e.message.partition(": ")
warn "syntax: #{message}" if code == "LORA_PARSE"
end

WASM / browsers

try {
db.execute("NOT CYPHER", null);
} catch (err) {
// Message format: "<CODE>: <human text>"
const [code] = err.message.split(": ", 1);
if (code === "LORA_PARSE") console.warn("syntax", err.message);
}

Why match on codes, not messages

Codes are the contract. Messages are advisory: between minor releases we rewrite individual #[error("...")] strings to make them clearer or include more context. Anything matching message text — if err.message.contains("not found") — will silently break. Match on LORA_NOT_FOUND instead.