Reference
Errors
Every error code, its status, and what to change.
Every error is a JSON object with a stable code, and a message naming the part of the request at fault when there is one:
{ "error": "unknown_column", "message": "password_hash" }A message never contains SQL or database text.
The request
| Code | Status | Means |
|---|---|---|
not_found | 404 | no such resource, or no such row, or a row you may not see |
method_not_allowed | 405 | the resource does not allow this method, or a procedure was called with another method than its own |
unknown_column | 400 | the column does not exist or is hidden |
unknown_relation | 400 | the relation does not exist |
unknown_operator | 400 | the operator is not one of eq neq gt gte lt lte in like ilike match imatch is ov cs cd |
bad_operator | 400 | the operator does not apply to the column's type |
invalid_value | 400 | the value does not fit the column's type |
bad_filter | 400 | a filter is not operator.value |
bad_logic | 400 | an or or and is not (term,term) |
bad_list | 400 | an in list is malformed, empty, or too long |
bad_name | 400 | a dotted or quoted name is malformed |
bad_syntax | 400 | unbalanced quotes or parentheses |
bad_select | 400 | a select item is malformed |
duplicate_select | 400 | a name is selected twice |
unknown_aggregate | 400 | not one of count sum avg min max |
bad_aggregate | 400 | the aggregate does not apply to the column's type |
aggregate_with_embed | 400 | a grouped read cannot embed relations |
aggregate_in_embed | 400 | an embed cannot hold aggregates |
bad_order | 400 | an order term names a to-many column, an unorderable type, or, in a grouped read, an unselected column |
not_embedded | 400 | relation.order, .limit or .offset names a relation that is not embedded |
too_deep | 400 | a path or an embed walks more relations than limits.depth |
too_many_filters | 400 | more filters than limits.filters |
bad_limit, bad_offset | 400 | not a whole number |
limit_exceeded | 400 | a limit over limits.maxPage |
bad_count | 400 | count is not exact or estimated |
unsupported | 400 | the database cannot do what was asked, e.g. a regular expression on SQLite |
Writes and procedures
| Code | Status | Means |
|---|---|---|
bad_body | 400 | the body is not an object or a list of objects within limits.bodyRows |
body_too_large | 413 | the body is over the adapter's size limit |
mixed_columns | 400 | the rows of a body name different columns |
not_writable | 400 | the column cannot be written by this method |
filter_required | 400 | a bulk update or delete has no filter |
out_of_scope | 403 | a value contradicts the host's scope |
unknown_argument | 400 | the procedure's function takes no argument of that name |
missing_argument | 400 | an argument without a default is missing |
bad_argument | 400 | a GET procedure's argument is given twice |
The database
| Code | Status | Means |
|---|---|---|
duplicate | 409 | a unique constraint refused the row |
reference_missing | 409 | a foreign key points to a row that does not exist |
still_referenced | 409 | the row is still referenced by another |
value_required | 400 | a required column has no value |
value_rejected | 400 | a check constraint refused the value |
forbidden | 403 | the database refused the session's role |
timeout | 503 | the statement ran past limits.timeoutMs |
internal | 500 | anything else; your onError hook receives it |