Skip to content

Error Codes

Every error Grafeo raises carries a machine-readable code of the form GRAFEO-<Category><Number>, and its message starts with that code (GRAFEO-Q002: semantic error: ...), so every binding can tell the kind of an error from its message. The code is stable across releases: once a number is assigned to a failure mode, it does not move.

In Python, catch grafeo.GrafeoError (subclass of RuntimeError) to inspect the structured attributes:

import grafeo

db = grafeo.GrafeoDB()
try:
    db.execute("NOT VALID GQL")
except grafeo.GrafeoError as e:
    print(e.error_code)    # "GRAFEO-Q001"
    print(e.gql_status)    # "42001", see GQLSTATUS below
    print(e.is_retryable)  # False

Categories:

Prefix Category Meaning
Q Query Parser, planner, or executor rejected a query
T Transaction Transaction lifecycle or isolation violation
S Storage On-disk state, WAL, or recovery
V Validation Input or reference does not resolve
X Internal Bug, I/O, or serialization

Query (Q)

Code Name Retryable Meaning
GRAFEO-Q001 QuerySyntax no Parser rejected the query. Check the reported line/column.
GRAFEO-Q002 QuerySemantic no Parsed but invalid: unknown label, graph or procedure, a variable nothing binds (in a stored procedure's body too), a call with another number of arguments, an unknown YIELD column, etc. GQLSTATUS 42002 for a name that resolves to nothing, 42000 for the rest.
GRAFEO-Q003 QueryTimeout yes Query exceeded its deadline. Raise query_timeout or narrow the pattern.
GRAFEO-Q004 QueryUnsupported no The database or this build cannot run the statement: a feature the build leaves out (vector or text indexes, procedures, RDF, an import format), a language of another graph model (GQL on an RDF database), an operation the database cannot do (a backup of an in-memory database), or an isolation level that is not available yet (SERIALIZABLE).
GRAFEO-Q005 QueryOptimization no Optimizer could not produce a plan. Report with the query text if you hit this.
GRAFEO-Q006 QueryExecution no A valid statement failed while it ran, on its data: a file to load that cannot be read, a SPARQL graph that exists already or does not exist, a write to a node the transaction deleted, an integer or decimal result out of range, a float converted to an integer outside its range, a division by zero, or text a cast cannot read as a number (GQLSTATUS 22003, 22012 and 22018).

Transaction (T)

Code Name Retryable Meaning
GRAFEO-T001 TransactionConflict yes Write-write conflict with another transaction. Retry the whole transaction.
GRAFEO-T002 TransactionTimeout yes Transaction exceeded its TTL.
GRAFEO-T003 TransactionReadOnly no Attempted a write inside START TRANSACTION READ ONLY.
GRAFEO-T004 TransactionInvalidState no COMMIT / ROLLBACK without an active transaction, a transaction command outside GQL, or START TRANSACTION, COMMIT or ROLLBACK run through a transaction object's execute (end it with its commit() or rollback() call).
GRAFEO-T005 TransactionSerialization no Reserved for Serializable isolation, which is refused for now (GRAFEO-Q004): no commit fails with this code until it returns.
GRAFEO-T006 TransactionDeadlock yes Lock manager detected a cycle. Retry.
GRAFEO-T007 DatabaseClosed no A write to a database whose close() started (persistent databases), or a checkpoint, backup or save after it. Open it again to write. Python raises DatabaseClosedError, a subclass of GrafeoError; the C API returns GRAFEO_ERROR_DATABASE.
GRAFEO-T008 IncompleteCommit no An earlier commit did not complete, so nothing commits, checkpoints, saves or copies the database (to_memory(), snapshots) until it is reopened (reads still work). Python raises GrafeoError; the C API returns GRAFEO_ERROR_DATABASE.
GRAFEO-T009 LogWriteFailed yes The commit could not be written to the write-ahead log (a full disk, an I/O error) and was rolled back: nothing of it is in the log or the database. Retry the transaction once the cause is gone.
GRAFEO-T010 CommitOutcomeUnknown no The commit was written to the write-ahead log, but the log could not be made durable. Nobody sees the commit, and whether it exists is known only after the database is reopened; nothing commits until then. Do not retry before the reopen: the commit may already be there. The C API returns GRAFEO_ERROR_DATABASE.
GRAFEO-T011 LogUnavailable no The write-ahead log takes no more writes after an earlier failure. Nothing of this commit was written, and nothing commits until the database is reopened. The C API returns GRAFEO_ERROR_DATABASE.

Storage (S)

Code Name Retryable Meaning
GRAFEO-S001 StorageFull no Buffer budget, disk, or memory limit reached.
GRAFEO-S002 StorageCorrupted no A file Grafeo wrote is damaged: a checksum, a header, a section or a WAL record that does not read back as written. The message names the file and, when known, the byte. Python raises GrafeoCorruptionError, a subclass of GrafeoError; the C API returns GRAFEO_ERROR_STORAGE. The database may need a restore from a backup.
GRAFEO-S003 StorageRecoveryFailed no WAL replay failed during GrafeoDB::open. Inspect the logs.
GRAFEO-S004 DatabaseLocked no The database file is open elsewhere: in this process (close the other handle first) or in another process (close it there). Python raises GrafeoLockedError, a subclass of GrafeoError. For several processes on one database, run grafeo-server.
GRAFEO-S005 BackupChainBroken no An incremental backup cannot continue its chain: the WAL segment where the last backup ended was removed, or the log has a gap. Nothing is written; take a new full backup to start a new chain.

Validation (V)

Code Name Retryable Meaning
GRAFEO-V001 InvalidInput no A value or name a call gives does not fit: wrong vector dimensionality, oversized property, a missing or ill-typed procedure argument, an index, named graph or embedding model that does not exist, an invalid setting, an import line or snapshot that is not valid, the manifest, cursor or full backup a restore needs that is missing, a write the graph's schema or a constraint refuses (GQLSTATUS G2000), and a DELETE of a node that still has edges (G1001).
GRAFEO-V002 NodeNotFound no NodeId does not exist in the current graph (a direct write to it, or an edge to it).
GRAFEO-V003 EdgeNotFound no EdgeId does not exist in the current graph (a direct write to it).
GRAFEO-V004 PropertyNotFound no Referenced property key is not declared for this label/type.
GRAFEO-V005 LabelNotFound no Referenced label is not declared.
GRAFEO-V006 TypeMismatch no Value type does not match the schema declaration.

Internal (X)

Code Name Retryable Meaning
GRAFEO-X001 Internal no A bug in Grafeo: an invariant of the engine does not hold. A mistake in a query, a call or its input never has this code. Please file a bug with the query and stack trace.
GRAFEO-X002 SerializationError no Could not encode/decode a value (snapshot, WAL, or binding boundary).
GRAFEO-X003 IoError no Underlying I/O call failed.

GQLSTATUS

Every error also carries its GQLSTATUS, the five-character status of ISO GQL (section 23): a class of two characters and a subclass of three. The Grafeo code says which part of Grafeo refused the statement, the GQLSTATUS says what kind of condition it is, as SQL's SQLSTATE does:

GQLSTATUS Condition Example
22003 numeric value out of range RETURN 9223372036854775807 + 1, an integer sum past 64 bits, a decimal sum past 38 digits, CAST(1.0e19 AS INT64), toInteger(Infinity)
22009 invalid time zone displacement value SESSION SET TIME ZONE 'Europe/Amsterdam': a time zone that is not a UTC offset, or one past 14 hours
22012 division by zero RETURN 10 / 0, RETURN 10 % 0
22018 invalid character value for cast CAST('Alix' AS INT64): text that spells no number, cast to an integer, a float or a decimal (toInteger('Alix') is null instead)
22G02 negative limit value LIMIT $k with k = -1
22G03 invalid value type LIMIT $k with k = 'three', a procedure argument of another type
22G04 values not comparable two values a comparison cannot compare, such as a node and a number in GQL
22000 data exception other failures on the statement's data, such as a vector of another size than its index or a property value past its size limit
G2000 graph type violation a write the graph's schema refuses: a property of another type than its node or edge type declares, a missing NOT NULL property, a label, edge type or property a closed graph type does not declare, a UNIQUE, NOT NULL or key constraint
G1001 dependent object error: edges still exist DELETE of a node that still has edges (use DETACH DELETE)
02000 no data a node or edge that does not exist
25000 invalid transaction state a write to a closed database, START TRANSACTION, COMMIT or ROLLBACK inside a transaction object (end it with its commit() or rollback() call), a commit or rollback of a transaction that already ended, a transaction past its timeout
08000 connection exception a database file another handle or process holds open (GRAFEO-S004)
25G03 read-only transaction a write or DDL in a read-only transaction or database
40000 transaction rollback a write conflict, a deadlock, a commit the write-ahead log could not take (GRAFEO-T009, GRAFEO-T011)
40003 transaction completion unknown a commit written to the log but not made durable (GRAFEO-T010), and every commit after an earlier one that did not complete (GRAFEO-T008)
42001 syntax error MATCH (n RETURN n
42002 invalid reference a name that resolves to nothing: an undefined variable, an unknown function, procedure, parameter, graph or type
42000 syntax error or access rule violation any other rule a statement breaks beyond the grammar (an aggregate in a WHERE, a wrong number of arguments, a pattern MERGE cannot take), a feature Grafeo lacks, and a permission the user does not have

42000 is the code ISO GQL gives a violated syntax or access rule that names no condition of its own; the message says which rule it is.

Python has it as GrafeoError.gql_status, Node.js and WASM as the gqlStatus property of the thrown Error (in Node.js next to errorCode, the Grafeo code, and isRetryable), C as grafeo_last_error_gql_status() (next to grafeo_last_error()), Go as the GQLStatus field of *grafeo.Error (get it with errors.As), C# as GrafeoException.GqlStatus and Dart as GrafeoException.gqlStatus. A float operation keeps its IEEE result (toFloat(1) / 0 is Infinity, 1.5e0 % 0 is NaN), and SPARQL leaves a variable unbound when its expression fails, as SPARQL 1.1 specifies, instead of raising one of these errors.

Retry guidance

Only codes flagged yes above are worth retrying automatically. Everything else signals a logical or structural issue that retrying will not fix. In Python:

import time

for attempt in range(3):
    try:
        db.execute(my_query)
        break
    except grafeo.GrafeoError as e:
        if not e.is_retryable or attempt == 2:
            raise
        time.sleep(0.05 * (2 ** attempt))

Stability

The codes above are stable API. New codes will be added for new failure modes; existing codes will not be renamed or reassigned. ErrorCode in Rust is #[non_exhaustive], and the Python string form is the canonical identifier to match against.