Common Query Errors (v2, Beta)
This page describes common errors on the v2 API and how to resolve them. A theme runs through v2: it fails loud. Conditions that a lenient API might turn into an empty result โ an unsupported operator, an unknown config profile, a missing test set โ return a 4xx with a message instead, because an empty result is indistinguishable from "no match" and hides the real problem.
The error response format
Every v2 error โ from any endpoint, at any status โ returns the same JSON envelope, so a client can parse errors one way across the whole API:
{
"kind": "error",
"data": {
"code": "not_found",
"message": "Unknown table 'invoicess'"
}
}
kindis always the literal string"error"โ the cheapest check for "did this request fail" (independent of the HTTP status).data.codeis a stable, machine-readable code (a dotted namespace) โ branch on this in an SDK. Codes are contractual; themessagewording is not.data.messageis a human-readable, single-line explanation โ surface it, but don't parse it.
The HTTP status carries the coarse class (4xx client, 5xx server); the code carries the specific cause. For an SDK, the reliable pattern is: if the body has "kind": "error", read data.code; otherwise treat the body as a normal result.
Code catalogue
Query and read endpoints (_query, _search, _predict, _recommend, _relate, _aggregate, _estimate, _evaluate, _sql, _batch):
code | HTTP | Cause |
|---|---|---|
query.invalid | 400 | The query shape is wrong โ a bad from, an unrecognised structure. |
request.invalid | 400 | A value failed validation (bad type, out-of-range argument). |
proposition.unsupported | 400 | A $-operator isn't applicable to the named field. |
json.malformed | 400 | The request body isn't valid JSON. |
not_found | 404 | A referenced table (the from, or a linked table) doesn't exist. |
operation.unsupported | 501 | A capability isn't implemented for this table/engine (e.g. a rep2-only operator on a legacy rep1 table). Distinct from 500 โ "not supported here", not "we crashed". |
internal | 500 | An unexpected server error. Report it. |
Data-write endpoints (_delete, _modify, .../batch, .../stream, .../import) and schema endpoints add:
code | HTTP | Cause |
|---|---|---|
data.bad_request | 400 | A write was rejected (e.g. a vector dimension mismatch, or on_conflict on a keyless table). |
import.failed ยท table.exists ยท schema.not_collection | 400 | Import problems: the import failed, the target table already exists, or it isn't a collection. |
schema.create_failed ยท schema.column_update_failed ยท schema.refresh_failed ยท schema.plan_failed ยท schema.apply_failed | 400 | The schema operation was rejected (the message says why). |
not_found | 404 | The named table/column doesn't exist. |
Two things this table makes explicit and worth relying on: a typo'd table name is a 404, not a 500 (it reads as "you referenced something missing", not "we crashed"), and an unsupported operation is a 501, not a 500 โ so a client can tell "this engine can't do that" apart from a genuine bug.
Success responses
For contrast, successful responses come in two shapes:
- Row results (
_search,_predicthits, filtered_query) return the v1-compatible body{ "offset": โฆ, "total": โฆ, "hits": [ โฆ ] }โ nokindfield (an absentkindmeans rows). - Non-row results (
_aggregate,_estimate,_evaluate,_batch) use the same{ "kind": โฆ, "data": โฆ }frame as errors โ e.g.{ "kind": "aggregate", "data": { โฆ } }. So the presence of"kind": "error"โ never just the presence ofkindโ is what marks a failure.
401 / 403 โ authentication and environments
Almost every auth failure on v2 is one of two things: wrong addressing or a read key used for a write.
There is no env-scoped API key. The same key that reads or writes master reads or writes every environment. An environment is selected purely by URL path โ never by a dot suffix, a request-body field, a query parameter, or a header:
โ
/db/{db}/env/{name}/api/v2/_query (multi-tenant server)
โ
/env/{name}/api/v2/_query (single-db server)
โ /db/{db}/env.{name}/api/v2/_query (dot โ not an env selector)
โ body: { "env": "{name}", ... } (ignored)
- 401 "not authorized to perform this operation" on a write (
PUT/DELETEschema,POST .../_batch) almost always means a read-only key. Reads succeed, writes 401 โ use a read-write key. - 403 / 401 on an env path that reads fine on
masteris almost always an addressing bug โ a dot instead of/env/, or a gateway rewriting the path. Confirm the env exists withGET /db/{db}/api/v2/_envs, then address it with the slash form above.
501 โ $patterns / relate on a legacy table
Error: 501 โ relate $patterns "supported on collections only".
Cause: the v2 _relate $patterns (itemset mining) endpoint requires a rep2 CollectionDb. Tables uploaded through the v1 API are legacy rep1 TableDb, and the v2 endpoint returns 501 for them by design. Two ways forward:
- Mine now, no rebuild: hit the legacy endpoint
POST /api/v1/_relateโ it mines rep1 tables today. - Everything on v2: re-upload the table as a
"type": "collection"(see Schema Migration).
Unknown field
Error: Unknown field 'fieldName' in table 'tableName'
Cause: the field name doesn't exist in the table schema.
- Field names are case-sensitive โ check the spelling.
- Verify available fields:
GET /api/v2/schema/{table}. - For linked fields use dot notation:
product.name, notproductName.
// Wrong โ field doesn't exist
{ "from": "products", "where": { "productName": "coffee" } }
// Correct
{ "from": "products", "where": { "name": "coffee" } }
Unknown table
Error: Unknown table 'tableName'
- Table names are case-sensitive.
- List tables:
GET /api/v2/schema. - Ensure the table was created before querying.
Type mismatch
Error: Type mismatch: expected 'expectedType', got 'actualType'
Use the JSON type the column declares:
// Wrong โ price is a number column
{ "from": "products", "where": { "price": "3.95" } }
// Correct
{ "from": "products", "where": { "price": 3.95 } }
Strings for Text/String, numbers for Int/Decimal, true/false for Boolean, arrays for Array/Set.
_similarity returns 404
Error: 404 Not Found on POST /api/v2/_similarity.
Cause: v2 deliberately does not expose a _similarity endpoint. Similarity is an in-query operator, not a separate dispatch surface โ which is strictly more flexible, because $similarity composes with any other filter.
// v1 style โ no v2 endpoint
POST /api/v2/_similarity โ 404
// v2 โ use the $similarity operator inside a query
{
"from": "products",
"orderBy": { "$similarity": { "name": "espresso machine" } },
"limit": 10
}
Use $similarity in orderBy, select, or where.
No test set on collection evaluate
Error: 400 โ evaluate on a collection with neither test nor testSource.
Cause: unlike v1 tables, a v2 collection evaluate has no implicit default test set. Omitting both is rejected rather than silently sampling 100 rows, so you never measure something you didn't scope.
// Wrong โ nothing scopes the test set
{ "evaluate": { "from": "products", "predict": "category" } }
// Correct โ a deterministic 20% fold
{ "test": { "$index": { "$mod": [5, 0] } },
"evaluate": { "from": "products", "where": { "name": { "$get": "name" } },
"predict": "category" } }
See the Evaluation guide (v2).
Unknown inference profile
Error: 4xx โ Unknown config.ai profile 'name'.
Cause: config.ai accepts fast (flat), and (v1), group (v2, the default), and high. An unrecognised name is rejected loudly, never silently ignored โ so a typo can't quietly downgrade your inference.
// Wrong
{ "from": "products", "predict": "category", "config": { "ai": "groupp" } }
// Correct
{ "from": "products", "predict": "category", "config": { "ai": "group" } }
Unsupported computed column
Error: 4xx describing the unsupported expression.
Cause: a computed / derived column expression that the v2 engine doesn't support fails loud rather than resolving to an empty value. This is by design โ a silent empty here would read as "no match" and mask the real cause.
Empty candidate set
Error: Empty candidate set / No matching rows.
Your filters matched nothing:
- Broaden the criteria, or verify the filtered values exist.
- Use
$matchfor fuzzy text instead of exact match:
// Exact match may return nothing
{ "from": "products", "where": { "name": "coffee" } }
// Fuzzy
{ "from": "products", "where": { "name": { "$match": "coffee" } } }
Empty $search / $knn. Multi-term $search and $knn/$nn match all query tokens (AND). A term that appears in no row empties the whole result โ near: "organic milk" returns nothing if "organic" is in no name, and $search "return policy refund" returns nothing if no single row has all three. Use OR or single terms ("$search": "return OR refund"), or the ranked search block, which orders by relevance instead of requiring every token: { "from": "prompts", "search": { "field": "prompt", "text": "refund" } }. Note that $search/$knn apply only to tokenized Text columns, not exact String columns.
Unknown operator
Error: Unknown operator '$operatorName'
- Operators are case-sensitive and start with
$. - Common v2 operators:
$match(full-text),$has(Set/Array contains),$gt/$gte/$lt/$lte,$and/$or/$not,$numeric,$similarity,$get,$context,$why. - See the Query Operator Reference (v2).
Invalid JSON syntax
Error: Invalid JSON at line X, column Y
Usual suspects: missing commas, trailing commas, single quotes, unquoted strings, unbalanced brackets.
// Wrong โ trailing comma
{ "from": "products", "where": { "name": "coffee", } }
// Correct
{ "from": "products", "where": { "name": "coffee" } }
Query timeout
Error: Query timeout / Request timeout
- Add
limitto bound the result set. - Use more specific
whereconditions. - After heavy writes,
optimizethe table and warm it โ see Warming Strategies (v2).
_predict returns a flat / uniform distribution
Not an error, but a common surprise: every candidate comes back at ~1/N (e.g. 0.02 across 50 values). The evidence isn't discriminating โ usually a high-cardinality target with only a few examples per value and only diffuse text signal, so there isn't enough per-value evidence to move off the prior.
- For open-ended "which known answer / article / template", use ranked
searchretrieval over the resolved history instead ofpredict(see Support Triage). - Reserve
predictfor lower-cardinality targets (type, category, route, assignee) where each class has many examples. - Add
"$why"โ if the factor tree shows only a base rate and no evidence factors, the evidence was below the detection threshold.
Values look wrong after an engine upgrade
If a column reads back implausibly โ a boolean that's all-true, a text column that lost its analysis, links that resolve empty โ the data may have been ingested by a build that predated the relevant fix. Some fixes are on the write path and do not repair already-stored data. Re-ingest the environment and re-check before assuming a live engine bug.
Related
- Limits & Timeouts (v2) โ request size, the 15-minute request timeout, pagination,
_batchfail-fast semantics, and the429backpressure model. - Destructive operations & data-loss safety โ why a dropped
/env/{name}/segment silently writes to production, and how to avoid it. - Query Operator Reference (v2) ยท Inference (v2) ยท Evaluation (v2)
- v1 Common Errors โ the classic-API version.