Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Taxonomy

Every public lunaris API returns Result<_, LunarisError>. LunarisError is one umbrella enum with a sub-enum per subsystem; the HTTP server maps each variant onto a status code (see Protocol → MemoryProtocol 0.1).

Source: crates/lunaris-core/src/error.rs.

LunarisError (umbrella)

#[non_exhaustive] — always include a wildcard arm when matching; new subsystems can be added in a patch release.

VariantWrapsMeaning
Storage(StorageError)backend / scheme / (de)serialization / IO faultsthe KV-vector-graph-queue substrate failed or was misconfigured
Extract(ExtractError)local-LLM extractor faultsonly reachable when the graph pipeline is on
Validate(ValidateError)input-validation faultsbad bi-temporal bounds, contradictions, missing confirmation token
Retrieve(RetrieveError)retrieval-operator faultsan operator in the DSL tree or its backend call failed
Consolidate(ConsolError)ACT-R consolidator faultsonly reachable when the consolidate pipeline is on

Sub-enums

StorageError

VariantNotes
Backend(String)the Moon backend returned a RESP-level error
NotSupported(&'static str)a capability the chosen backend doesn’t offer
UnsupportedScheme(String)the URL passed to Lunaris::open / lunaris::open had a scheme other than moon:// — every other spelling was retired in 0.7.0
Serde(serde_json::Error)a stored value could not be (de)serialized
Io(std::io::Error)socket / file IO failure

ExtractError

Timeout (the extractor model didn’t answer in budget) · GrammarReject(String) (the model’s output failed the constrained-decoding grammar) · Backend(String).

ValidateError

VariantNotes
Temporalvalid_from >= valid_to on a primitive
Contradiction(String)the validator detected a contradiction it routed to the verifier
ConfirmationRequired(String)forget(...).hard() was called without a confirmation token — do a dry_run + confirm_hard_forget round-trip first (see Guides → Forgetting)

RetrieveError

OperatorFailed(String) (an operator in the retrieval tree errored) · Backend(String).

ConsolError

ActivationUnderflow (ACT-R base-level activation went negative — a calibration bug) · Backend(String).

HTTP mapping (lunaris-server)

Rust errorHTTP statuserror code
ValidateError::ConfirmationRequired428 Precondition Required (re-issue the dry_run + confirmation_token flow)confirmation_required
ValidateError::Temporal, ValidateError::Contradiction (and every other ValidateError)400 Bad Requestvalidate
StorageError::NotSupported (a capability the chosen backend doesn’t offer)501 Not Implementednot_supported
StorageError::UnsupportedScheme400 Bad Requestunsupported_scheme
request body carrying a scope / tenant field (forbidden by #[serde(deny_unknown_fields)])422 Unprocessable Entity(serde rejection)
missing / invalid bearer token401 Unauthorizedunauthorized
valid token without the verb the route requires403 Forbiddenforbidden
per-tenant rate limit exceeded429 Too Many Requests(empty body; Retry-After header)
every other StorageError, RetrieveError, ExtractError, ConsolError, unmapped LunarisError500 Internal Server Errorstorage | retrieve | extract | consolidate | unknown

A handful of statuses are produced by handler-local validation rather than map_error — these are not LunarisError variants:

Server causeHTTP statuserror code
mode: "graph" on a backend without graph_native and with the graph pipeline off (routes/recall.rs)501 Not Implementedgraph_mode_unavailable
malformed as_of (not RFC-3339) on /v1/recall400 Bad Requestinvalid_request
malformed confirmation_token (not a serialized ForgetReceipt) on /v1/forget400 Bad Requestinvalid_confirmation_token
malformed snapshot Lsn path segment on /v1/snapshot/{lsn}400 Bad Requestinvalid_lsn
{id} path segment on /v1/episode/{id} is not a valid Crockford base-32 ULID400 Bad Requestinvalid_episode_id
{lsn} wall_ms on /v1/snapshot/{lsn} is strictly greater than the engine’s current wall clock404 Not Foundsnapshot_out_of_range
no episode found for {id} in the caller’s JWT-bound scope on /v1/episode/{id}404 Not Foundepisode_not_found
/metrics requested while --metrics-disabled is set404 Not Found(plain-text body)

The auth / rate-limit middleware emits 401 / 403 / 429 before the LunarisError → status map runs (crates/lunaris-server/src/middleware/error.rs::map_error); that map only covers business-logic errors. map_error also increments lunaris_error_total{kind=…} for every error it handles.

The wire-level error body shape is specified in MemoryProtocol 0.1.