Errors and recovery
Treat an error as a result with a defined recovery path. Do not convert it to a neutral probability or silently drop a question from evaluation.
| Code | Typical cause | Appropriate response |
|---|---|---|
invalid_json | Syntax, unknown fields, wrong types, invalid probability during decoding | Correct the request; no command executed |
validation | Impossible evidence, incoherent probabilities, bad timeline, stale predecessor | Reconsider inputs or read current state; do not fabricate a substitute number |
not_found | Missing question/version key | Check target identity; create the intended question if appropriate |
conflict | Reused request ID with different content, duplicate persisted key, SQL constraint | Reconcile intended mutation with existing state |
busy | SQLite could not obtain a required lock within five seconds | Back off and retry the identical mutation/ID |
storage | Other SQLite or journal failure | Preserve the database, inspect the fault, and restore only through a verified procedure |
request_too_large | Line exceeds 1 MiB | Reduce/split the operation where semantics permit; restart the process |
Core validation errors are mapped to validation after a request is decoded. A numeric probability rejected by transport decoding instead appears as invalid_json. Error messages explain a specific failure but are not a stable machine enum; branch on the code and your operation context.
Failed writes are atomic
A mutation validates under the database transaction and commits its event and receipt together. Failure in either insert rolls back both. The test suite injects a receipt-write failure after the event insert to verify that no partial event survives.
A failed mutation does not consume the request ID. You can fix a previously uncommitted request and submit it under that ID, although recording a distinct attempt ID can be useful at the application layer. After a successful mutation, the ID is bound to its decoded content.
Stale revisions
If another worker appends after you read the ledger, your predecessor becomes stale. Reading the newest revision and blindly substituting its ID is unsafe: the evidence may already be incorporated or the assumptions may have changed. Recompute the intended update against the new history.
Impossible evidence
When a supplied observation has zero probability under the entire current model, Bayesian updating cannot produce a valid posterior. This is a model error. Inspect the event definition, prior, likelihoods, and observation claim. Returning 0.5 would hide the failure.
Startup and output failure
An invalid database, unsupported schema version, unavailable filesystem path, or failed output write can stop the process with exit code 2. These failures may not have a JSON response. If a response was lost, use idempotent replay to determine whether the intended mutation committed.
The library does not automatically repair an unknown schema or delete damaged history. Keep backups and the release version that created them. See storage and operations for the supported local workflow.