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.

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/DELETE schema, 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 master is almost always an addressing bug โ€” a dot instead of /env/, or a gateway rewriting the path. Confirm the env exists with GET /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, not productName.
// 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 (the default), and high (v2). 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 $match for 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 limit to bound the result set.
  • Use more specific where conditions.
  • After heavy writes, optimize the 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 search retrieval over the resolved history instead of predict (see Support Triage).
  • Reserve predict for 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.