Skip to content

Errors

Every error that pg_crdt raises, with its SQLSTATE, and the errors from Postgres that you can meet when you use it. Match on the SQLSTATE (error.code in node-postgres), not on the message text. Messages of the extension start with the name of the function and carry a HINT.

SQLSTATE Name Raised by When
22004 null_value_not_allowed pn_increment, pn_decrement replica or amount is null.
22023 invalid_parameter_value pn_increment, pn_decrement amount is negative; replica is not a valid entry key ('', abc:, :x).
22023 invalid_parameter_value pn_apply_delta replica is empty or contains :; a count in the delta is not a whole number from 0 to 9223372036854775807; a key in the delta is malformed.
22023 invalid_parameter_value pn_value (Postgres) An entry is not a number. Only a state that did not pass pn_is_valid can have one.
22003 numeric_value_out_of_range pn_increment, pn_decrement (Postgres) An entry would pass 9223372036854775807 (bigint out of range).
22003 numeric_value_out_of_range pn_value (Postgres) The value is outside the bigint range.
23514 check_violation The crdt.pn domain, so any function that takes or returns one A value is not a crdt.pn envelope: not an object, other keys than t, v, p, n, t not "pn", v not 1, or p or n not an object.
42501 insufficient_privilege pn_apply_delta replica is null (no identity), or an entry of the delta belongs to another replica.
42501 insufficient_privilege The install script The schema crdt is owned by another non-superuser role, or another role has CREATE on it.
22004 null_value_not_allowed yseq_insert, yseq_delete, yseq_set replica, a position, a length or the text is null.
22023 invalid_parameter_value yseq_insert, yseq_delete, yseq_set A position or range outside the text, or a negative length; replica is not an entry key or is longer than 256 bytes; for yseq_set, a base with another document id, or with characters the state lacks.
22023 invalid_parameter_value yseq_apply replica is not a replica id; ops is not an op or an array of ops; a malformed op, insert run or delete; an op that breaks a causal rule or a limit (the message names it, V0 to V6: no v, more than 128 runs, a key over 256 bytes).
22023 invalid_parameter_value yseq_merge An argument is not a well-formed state beyond the envelope, or the two states have different document ids.
22023 invalid_parameter_value yseq_ops_since vv is not an object of whole numbers from 0.
22003 numeric_value_out_of_range yseq_insert, yseq_set The entry key has used up its sequence numbers (2,147,483,647 characters).
23514 check_violation The crdt.yseq domain, so any function that takes or returns one A value is not a crdt.yseq envelope (wrong keys, t not "yseq", v not 1, arrays of different lengths).
42501 insufficient_privilege yseq_apply replica is null (no identity), or an insert carries another writer’s key.
54000 program_limit_exceeded yseq_apply The writer would have more than 32 entry keys in the state, or more waiting than its quota (256 runs plus deletes, or 64 kB).
54000 program_limit_exceeded yseq_ops_since, yseq_diff, yseq_merge (Postgres) requested character too large for encoding: the database is not UTF8 and the state has deleted characters. yseq_ needs a UTF8 database.
XX000 internal_error yseq_ops_since, yseq_diff, yseq_merge A state has runs whose origins are missing. It means a bug, or a hand-made state: report it.
22023 invalid_parameter_value ydoc_create The id is null, empty, longer than 256 bytes or has a control character.
23505 unique_violation ydoc_create A document with this id exists. Creating is not idempotent: the existing document is never returned, so that nobody can take over a document by creating its predictable id. Two sessions that create one id at once get one success and one 23505. See Create a document with a client-chosen id.
22004 null_value_not_allowed ydoc_insert, ydoc_delete, ydoc_set, ydoc_rejected_purge replica, a position, a length or the text is null; for ydoc_rejected_purge, doc is null.
22023 invalid_parameter_value ydoc_insert, ydoc_delete, ydoc_set A position or range outside the text; replica is not an entry key or is longer than 256 bytes; a base that is not a version of the document, or is older than its last compaction.
22023 invalid_parameter_value ydoc_apply, ydoc_merge A malformed op; for ydoc_apply, an op without v, or one that breaks a causal rule (the message names it, V0 to V6); the same ids sent again with other text or origins. ydoc_apply also: replica is not a replica id.
22023 invalid_parameter_value ydoc_ops_since, ydoc_compact vv is not an object of whole numbers from 0; horizon outside 0 to the document’s write counter.
42501 insufficient_privilege ydoc_apply replica is null (no identity), or an insert carries another writer’s key.
42501 insufficient_privilege Any ydoc_ function (Postgres) The caller has no privileges on the crdt.ydoc_* tables (permission denied for table ydoc_docs). This is the intended result for a client role: see Collaborative text for a blog post.
54000 program_limit_exceeded ydoc_apply A quota of the untrusted path: more than 256 runs in one op, more than 16 device keys per owner and document, origins too far apart to check (250,000 rows), or too many waiting ops for the writer (100 ops or 256 kB).
54000 program_limit_exceeded Any ydoc_ write The order labels of a document ran out (document ... has too many rows). Not reachable at realistic sizes.
P0002 no_data_found Every ydoc_ function that writes, ydoc_ops_since and ydoc_version The document does not exist. The readers ydoc_value, ydoc_length and ydoc_base return null instead.
XX000 internal_error ydoc_ internals An invariant of a document’s rows is broken (no row labelled ..., ... is not inside the run). It means a bug, or a direct write to the tables: report it.

Several rows share a SQLSTATE for different reasons. Tell them apart with the message.

Text that is written by the extension, as Postgres reports it:

SQLSTATE Message
22004 crdt.pn_increment: replica and amount must not be null
22023 crdt.pn_increment: 'abc:' is not a replica key
22023 crdt.pn_increment: amount must be zero or more, got -3
22023 crdt.pn_apply_delta: 'a:b' is not a replica id
22023 crdt.pn_apply_delta: the delta has an entry that is not an integer from 0 to 9223372036854775807
22023 crdt.pn_apply_delta: entry p.'alice:' is not a replica key
42501 crdt.pn_apply_delta: the writer has no replica id
42501 crdt.pn_apply_delta: replica 'alice' cannot write entry p.'bob' of another replica
42501 schema crdt is owned by role other, not by the installing role app_owner
42501 another role has CREATE on schema crdt
23514 value for domain crdt.pn violates check constraint "pn_check" (Postgres)
22004 crdt.yseq_insert: replica must not be null
22023 crdt.yseq: range at position 20 of length 0 is outside the text (length 11)
22023 crdt.yseq_insert: 'a:' is not a replica key
22023 crdt.yseq_set: the base belongs to another document (id ... against ...)
22023 crdt.yseq_set: the base has characters the state lacks, so it is not a version of this document
22023 crdt.yseq_merge: the states belong to different documents (ids ... and ...)
22023 crdt.yseq_merge: argument a: not a well-formed crdt.yseq state
22023 crdt.yseq_apply: op rejected (V2: a run does not start at v[replica] + 1)
22023 crdt.yseq_apply: malformed insert run ["bob", 1, null, null, ""]
42501 crdt.yseq_apply: the writer has no replica id
42501 crdt.yseq_apply: replica 'frank' cannot insert characters of replica 'gina'
54000 crdt.yseq_apply: writer 'bob' has too much waiting (... runs and deletes, ... bytes)
23514 value for domain crdt.yseq violates check constraint "yseq_check" (Postgres)
22023 crdt.ydoc_create: '' is not a document id
23505 crdt.ydoc_create: document 'welcome' already exists
22023 crdt.ydoc_insert: position 99 is outside the document (length 11)
22023 crdt.ydoc_set: base is not a version of document 'welcome'
22023 crdt.ydoc_set: base 3 of document 'welcome' is older than its last compaction
22023 crdt.ydoc_apply: V0: ops carry no version vector "v"
22023 crdt.ydoc_apply: V2: insert bob:3 does not follow "v" (expected seq 1)
22023 crdt.ydoc: insert bob:1 reuses ids with other content or origins
42501 crdt.ydoc_apply: the writer has no replica id
42501 crdt.ydoc_apply: replica 'dave' cannot insert characters of replica 'erin'
42501 permission denied for table ydoc_docs (Postgres)
54000 crdt.ydoc_apply: replica 'bob' has too many ops waiting in document 'welcome'
P0002 crdt.ydoc_insert: document 'nope' does not exist

pn_decrement raises the same messages with its own name, and yseq_delete and yseq_set the yseq_insert ones. Position errors of the yseq_ edits name crdt.yseq. The messages that name an entry show the map (p or n) and the key. The ydoc_ messages name the function, a document by its id in quotes, and a character as key:seq.

SQLSTATE When What to do
40001 A merge under REPEATABLE READ or SERIALIZABLE, when the row changed and committed after your snapshot (could not serialize access due to concurrent update). Run the whole transaction again. See Update safely.
22P02 crdt.current_replica_id(), when request.jwt.claims is set to text that is not valid JSON. Fix whatever sets the setting.
2BP01 drop extension pg_crdt, while a column, default or index uses crdt.pn or crdt.yseq, or a foreign key references crdt.ydoc_docs. Copy your data out first. See Uninstall.
23503 crdt.ydoc_drop, while a row of your table references the document. Delete your row first, in the same transaction.
40001 A yseq_ column update under REPEATABLE READ or SERIALIZABLE, when the row changed after your snapshot, as for any update. Run the whole transaction again.
40001 A ydoc_ write under REPEATABLE READ or SERIALIZABLE that waited for another write to the same document. Run the whole transaction again.
42501 An update of a column the role has no privilege on. This is the intended result for a writer without access. See Accept writes from untrusted clients.
  • 42501 from pn_apply_delta means the caller sent an entry that is not its own, or has no identity. Treat it as a rejected request. An honest client never causes it. A wrong identity setup does.
  • 22023 from pn_apply_delta means the delta is malformed. An honest client does not cause it.
  • 23514 means the value is not a counter at all: a wrong t or v, or a missing key.
  • 40001 is expected under the stricter isolation levels and is safe to retry.
  • 22003 means a total reached the 64-bit limit. See Limits.
  • 42501 from a ydoc_ function is either the identity check of ydoc_apply (a forged insert, or no identity: reject the request) or Postgres refusing a role without table privileges (call through your wrapper).
  • 22023 from ydoc_apply means the op is malformed or breaks a causal rule. An honest client running the same algorithm does not cause it; a client with a bug does. Resync it with ydoc_ops_since.
  • 22023 from ydoc_set with base ... is older than its last compaction means the form is older than the compaction horizon. Reopen the document and apply the change again.
  • 23505 from ydoc_create means the id is taken. If your client chose it, your wrapper decides what that means: the owner’s retry gets the same document, anyone else is refused. Never answer it by handing out the existing document.
  • 42501 from yseq_apply is its identity check: a forged insert, or no identity. Reject the request.
  • 22023 from yseq_apply means the op is malformed or breaks a causal rule. Resync the client with yseq_ops_since.
  • 22023 from yseq_merge or yseq_set about another document means a state or base from another row: check which row the value came from.
  • 54000 from ydoc_apply is a quota. A writer with too many waiting ops is sending ops whose dependencies never arrive: send the missing ops first.