reldir

Errors and exit statuses

Codes are a stable contract: each keeps its meaning, so scripts and agents may depend on them. A code always carries the same exit status – the status is a property of the failure, never of the command that met it – and this page is generated from the one registry the binary itself uses.

Exit statuses

| Status | Meaning | |—|—| | 0 | success; for check, a valid database | | 1 | a flag, argument, path, setting or input the command cannot accept | | 2 | the database is invalid, or a change was refused because it would make it so | | 3 | another writer or an outside edit moved what the command depended on; nothing was written, and retrying is safe | | 4 | a name that does not resolve, or a query that cannot be answered as asked – outside the SQL surface, or beyond its configured limits | | 5 | an interrupted transaction cannot be completed without a decision | | 6 | the format, history or metadata cannot be trusted, or I/O failed | | 7 | findings under --strict | | 8 | inference could not describe the data | | 9 | a decision is required: confirm with --yes, choose a policy, or authorise | | 10 | there is no database here, and --no-auto forbade making one | | 11 | the filesystem cannot keep the commit protocol’s promises | | 12 | the change is committed and visible, but finishing it on disk failed; recovery completes it – do not retry the change | | 13 | whether the change committed cannot be known; inspect the database before retrying | | 70 | reldir itself failed; please report it |

When a command meets several faults at once, the most severe decides its status: untrustworthy metadata or format (6) outranks an interrupted transaction (5), which outranks an invalid state (2). A warning is reported and never sets a status; lint findings set one only under --strict (7).

A change that fails with 12 (COMMITTED_RECOVERY_PENDING) was made: it is durable and every reader already sees it; only finishing it on disk is outstanding, and the next writing command or reldir recover completes it. Retrying the change would apply it twice. A change that fails with 13 (COMMIT_UNKNOWN) may or may not have been made; look before retrying, or give every change an --idempotency-key, which makes a retry safe whatever happened.

Codes

Finding and opening a database

Code Exit Meaning
PATH_NOT_FOUND 1 --db or RELDIR_DB names something that does not exist
PATH_NOT_DIRECTORY 1 --db or RELDIR_DB names a file
ROOT_AMBIGUOUS 1 a folder of pins without .db/ sits inside another database; name the one you mean
ROOT_JSON_AMBIGUOUS 1 JSON files at the root belong to no table
UNINITIALIZED 10 there is no .db/, and nothing may create one
ALREADY_INITIALIZED 1 init where .db/ exists
FORMAT_UNSUPPORTED 6 .db/ or a revision is in a format this binary does not read
FORMAT_MISSING 6 .db/ has no format marker and holds history or a transaction; --rebuild-metadata discards the history
FORMAT_UPGRADE_REQUIRED 6 .db/ is in format 2; reldir upgrade converts it
CONFIG_INVALID 1 .db/config is unreadable, too large, or holds an unknown or unusable setting
UNSAFE_FILESYSTEM 11 a write on a network, cluster, FUSE, FAT, shared-folder or unrecognised filesystem without allow_remote_filesystem
READ_ONLY 1 a change through a database opened read-only
USAGE 1 an argument the command cannot accept
INPUT_INVALID 1 input given to a command is not what it accepts (malformed JSON, CSV or JSON Lines)
IO_ERROR 6 a file operation failed; the path is named

Structure

Code Exit Meaning
UNEXPECTED_FILE 2 a file in a table or schema directory that is not .json
UNGOVERNED_DIRECTORY 2 a top-level directory no schema governs
NON_REGULAR_FILE 2 a symlink, socket, FIFO, device or hard-linked file where a row or schema belongs
PATH_COLLISION 2 two schema names equal under case or Unicode folding
PORTABILITY_COLLISION 2 two row files whose names are equal under case or Unicode folding, which one filesystem keeps apart and another merges
PATH_VIOLATION 1 a path that escapes the root or reaches into reldir’s metadata, or an unusable name
FILENAME_TOO_LONG 2 a row’s identity renders to a file name longer than the filesystem allows
FILENAME_RULE_UNDETERMINED 2 a key needs a character the table’s file names have never used, so no name can be chosen without inventing a convention
CROSS_DEVICE 11 a table directory is on another device than .db/, so a change cannot be renamed into place atomically

Schemas

Code Exit Meaning
SCHEMA_INVALID_JSON 2 the schema file is not JSON
SCHEMA_MISSING_REQUIRED 2 a required member of the schema is absent
SCHEMA_UNKNOWN_KEY 2 a member that is no keyword, at any depth; the message names the nearest one
SCHEMA_UNKNOWN_FORMAT 2 a format that is no format JSON Schema defines
SCHEMA_GRAMMAR 2 the document breaks the dialect’s grammar, or does not compile
SCHEMA_REF_EXTERNAL 2 a $ref leaves the document
SCHEMA_TABLE_NAME_MISMATCH 2 x-reldir.table is not the file’s name
SCHEMA_INVALID_TABLE_NAME 2 a table name breaks the naming rule
SCHEMA_TYPE_UNKNOWN 2 an unknown column type
SCHEMA_TYPE_TAG_CONFLICT 2 an x-reldir-type tag contradicts the subschema’s type
SCHEMA_COLUMN_UNKNOWN 2 a constraint names a column that does not exist
SCHEMA_COLUMN_EXISTS 2 a migration adds a column that exists
SCHEMA_TABLE_EXISTS 2 a migration adds a table that exists
SCHEMA_CONSTRAINT_EXISTS 2 a migration adds a constraint that exists
SCHEMA_IDENTITY_INVALID 2 x-reldir.identity names unknown, repeated, nullable, optional or non-scalar columns
SCHEMA_DEFAULT_TYPE_MISMATCH 2 a default or generator does not fit its column, or a column has both
SCHEMA_CONSTRAINT_NAME_DUPLICATE 2 two constraints share a name
SCHEMA_REFERENCE_PATH_INVALID 2 a reference path does not parse, or cannot reach a scalar through the schema
SCHEMA_FK_TARGET_MISSING 2 a foreign key’s target table or domain has no schema
SCHEMA_FK_TARGET_INVALID 2 a foreign key’s target is malformed
SCHEMA_FK_TARGET_NOT_UNIQUE 2 a foreign key’s target columns are no key of the target
SCHEMA_TARGET_KEYS_OVERLAP 2 the tables a reference may name do not share one key namespace
SCHEMA_FK_TYPE_MISMATCH 2 a reference cannot equal the key it names
SCHEMA_FK_ACTION_INVALID 2 a referential action could write a value the schema or contract forbids
SCHEMA_KEY_NOT_SCALAR 2 a key column is an array, object or json
SCHEMA_DOMAIN_KEY_INVALID 2 the tables of an identity domain do not key on one comparable column
SCHEMA_ACYCLIC_INVALID 2 an acyclic graph’s edges do not lead from a row to keys of its own table
SCHEMA_CHECK_INVALID 2 a check is not a deterministic expression over the row’s own columns
SCHEMA_ASSERTION_INVALID 2 an assertion is not a deterministic query returning the keys of rows that break it
SCHEMA_CONFLICT 2 inference disagrees with an existing schema, and the policy is to fail

The observed contract

Code Exit Meaning
CONTRACT_WIDENING_REQUIRED 2 a change would write a value the table’s contract has never admitted; widening it is a decision
CONTRACT_EXCEEDED 2 a file edited outside reldir holds a value the table’s inferred contract never admitted
CONTRACT_REDERIVED 0 an inferred contract’s file was missing and was restored, byte for byte, from recorded history

Rows

Code Exit Meaning
INVALID_JSON 2 the file is not one JSON document
MERGE_CONFLICT 2 the file holds a merge’s conflict markers: both sides of a merge changed a member differently
ROW_ROOT_NOT_OBJECT 2 a row file holds something other than one JSON object
SCHEMA_VIOLATION 2 a value breaks its subschema
TYPE_MISMATCH 2 a value is not of its column’s type
ROW_MISSING_FIELD 2 a required member is absent
ROW_UNKNOWN_FIELD 2 a member the schema does not declare
NOT_NULL_VIOLATION 2 a null where the column admits none
IDENTITY_MISMATCH 2 a file is not named by its row’s identity
KEY_COLLISION 2 two rows’ identities name one file
FILE_TOO_LARGE 2 a file is larger than max_json_file_size, so it is not read
NESTING_TOO_DEEP 2 a document nests deeper than max_nesting_depth, so it is not read

Keys, references and rules

Code Exit Meaning
PRIMARY_KEY_VIOLATION 2 two rows share a primary key
UNIQUE_VIOLATION 2 two rows share a unique key
DOMAIN_KEY_VIOLATION 2 two tables of one identity domain hold the same key
FOREIGN_KEY_VIOLATION 2 a reference names no row, or a change would leave one that does not
CYCLE_VIOLATION 2 a graph declared acyclic holds a cycle
CHECK_VIOLATION 2 a row fails one of its table’s checks
ASSERTION_VIOLATION 2 a row is named by an assertion over many rows

Changes

Code Exit Meaning
MUTATION_CONFLICT 2 a change names one file twice, or two changes to one row disagree
MIGRATION_REFUSED 9 a migration cannot be carried out exactly as the schema is written; the message says what to edit by hand
DECISION_REQUIRED 9 the command needs a confirmation, a policy or an authorisation it was not given

Queries and names

Code Exit Meaning
RESOURCE_LIMIT 4 a configured limit was exceeded; the answer is refused, never truncated
QUERY_UNSUPPORTED 4 a statement outside the SQL surface, or one that does not parse
QUERY_TYPE_ERROR 4 a value SQL produced cannot be stored in its column
UNKNOWN_TABLE 4 no such table
UNKNOWN_COLUMN 4 no such column
UNKNOWN_ROW 4 no row has that key
UNKNOWN_CONSTRAINT 4 no constraint has that name
UNKNOWN_REVISION 4 no revision has that number or id
UNKNOWN_SNAPSHOT 4 no snapshot has that name
UNKNOWN_RESOURCE 4 no MCP resource has that URI
CURSOR_STALE 3 a page cursor belongs to a state the database has since left

Transactions and concurrency

Code Exit Meaning
LOCK_CONTENDED 3 another writer held the lock past the wait
CONCURRENT_MODIFICATION 3 a file a change was planned against moved before it was written
PATH_INTERFERENCE 3 a path a change needs is not what it must be (a directory where a file goes, a symlink ancestor)
PLAN_CHANGED 3 a planned change no longer matches the state it would be committed to
TRANSACTION_INCOMPLETE 5 an interrupted transaction’s journal cannot be read
RECOVERY_BLOCKED 5 recovery could not place a committed file; the path and the failure are named
COMMITTED_RECOVERY_PENDING 12 the change is committed and visible, and finishing it on disk failed; do not retry it
COMMIT_UNKNOWN 13 making the commit durable failed and could not be retracted
TRANSACTION_EXPIRED 3 a transaction held the writer lock longer than transaction_timeout_seconds and was rolled back
TRANSACTION_STATEMENT 1 a statement that cannot run inside a transaction, or transaction control out of place
SNAPSHOT_READ 0 a writer was committing, so a read answered from the database as of its last commit

History and snapshots

Code Exit Meaning
INTERNAL_METADATA_CORRUPT 6 history, an object, the mirror or other metadata fails verification
HISTORY_DIVERGED 0 history has more than one head; the next recording merges them
SNAPSHOT_EXISTS 1 a snapshot with that name exists

Inference

Code Exit Meaning
INFER_NO_ROWS 8 a table has no rows to infer from
INFER_INVALID_JSON 8 a file inference must read is not JSON
INFER_ROOT_NOT_OBJECT 8 a file inference must read is not one JSON object
INFER_NON_JSON_FILE 8 a table directory holds a file that is not .json
INFER_NESTED_DIRECTORY 8 a table directory holds a directory
INFER_NON_REGULAR_FILE 8 a table directory holds a symlink, device or hard-linked file
INFER_KEY_INVALID 8 a column chosen with --pk is absent or null in a row, so it cannot identify every row
INFER_FILENAME_INCONSISTENT 8 the key chosen with --pk does not name the table’s files, and adopting a folder never renames them

Lint

Code Exit Meaning
LINT_SCHEMA_UNPINNED 7 the table is governed by an inferred contract nobody pinned
LINT_NULLABLE_NEVER_NULL 7 a column admits null, and no row is null
LINT_WIDER_TYPE 7 a column’s values all have a narrower type than it declares
LINT_ENUM_CANDIDATE 7 a string column with few distinct values
LINT_UNIQUE_CANDIDATE 7 every row holds a different value
LINT_CHECK_CANDIDATE 7 an int that is never negative, a string that is never empty
LINT_MIN_ITEMS_CANDIDATE 7 an array that is never empty
LINT_FK_CANDIDATE 7 values at some path all name rows of one table, and no foreign key says so
LINT_DOMAIN_CANDIDATE 7 values at some path each name a row of one of several tables whose keys never collide
LINT_FK_ACTION_DEFAULTED 7 a foreign key does not say what happens when its target is deleted or re-keyed
LINT_PK_NOT_GENERATED 7 a uuid or ulid key every insert must supply
LINT_COLUMN_NEVER_POPULATED 7 no row holds a value in a column
LINT_INCONSISTENT_PRESENCE 7 some rows have a column and others do not
LINT_ADDITIONAL_FIELDS_ALLOWED 7 the schema accepts members it does not declare
LINT_NON_CANONICAL_FORMATTING 7 rows not in their table’s recorded style
LINT_NO_DESCRIPTION 7 a table or column without a description

reldir itself

| Code | Exit | Meaning | |—|—|—| | INTERNAL_ERROR | 70 | reldir failed; the message says what it was doing |