Knowhere

Error Codes

A failed tool call comes back as:

<CODE>: <message> (hint: <one-line guidance>)

The code is stable and machine-readable — branch retry logic on it. The hint is one sentence of self-correction guidance, for a human.

Query

AREA_REQUIRED — every query must name one area. Add (area=<snake_case>) or "$area": "<snake_case>". From geocode it means something else: that tool takes an area parameter and has no directive syntax at all, so pass area, name a state in the text itself, or resolve the area first with list_areas(filter: "<place name>").

AREA_NOT_FOUND — no such area here. The message lists up to five close candidates; list_areas is authoritative. Names are snake_case and lower-case (new_york, not New York).

SYNTAX_INVALID — bracket syntax would not parse: missing bracket, unknown element type, malformed operator. See knowhere://docs/query.

INVALID_JSON — the query starts with { but is not valid JSON. Check trailing commas and quoting, or rewrite in bracket syntax.

UNSUPPORTED_DIRECTIVE — a top-level $key that is not $type, $area, $bb, $around, $id, or $and. Tag filters use plain keys, no $.

UNSUPPORTED_OPERATOR — an unknown tag operator, or $regex with modifiers. Operator list is in knowhere://docs/query.

INVALID_OPERATOR_VALUE — right operator, wrong value type: $in with a non-array, $exists with a non-boolean, $gt with a string.

INVALID_BOUNDING_BOX — not an array, not a multiple of four coordinates, or inverted. Use [minLon, minLat, maxLon, maxLat] with min <= max.

INVALID_COORDINATES — latitude outside [-90, 90], longitude outside [-180, 180], or NaN/Inf. Check the ordering too: geometry is longitude first.

QUERY_TOO_LONG — the generated SQL passed 1,000,000 characters. Narrow with more specific filters, a smaller area, or a bounding box.

QUERY_TIMEOUT — same fix. count_only and a tight (bb=…) are the cheapest narrowings.

TOO_MANY_RESULTS — the query matched more rows than the server will hold in memory at once. It is refused rather than truncated: truncation would hand back a wrong answer that reads exactly like a complete one. Narrow the area, add tag filters, or split the work by bounding box.

The cap depends on which tool raised it. From runtime's query.execute and query.union it is 50,000, and query.count() answers the how-many question with no cap at all. From near it is 100,000 per side, the message names which side overran, and there is no count-only equivalent — narrow the find or near query itself.

QUERY_EXECUTION — the SQL engine could not run it. Usually server-side; retry after adjusting, and if it persists the server may be misconfigured.

QUERY_UNKNOWN — a category unknown to the classifier. Read the message.

Routing

Behaviour behind these is in knowhere://docs/routing.

NO_ROUTING_DATA — the area has no road graph, because it was built with routing disabled. Straight-line tools still work.

NO_ROUTE — both ends snapped, but nothing connects them. Almost always different areas; routing never crosses an area boundary. On profile: "foot" it can also be an isolated footway, which is common in OSM.

NO_ROAD_NEARBY — nothing usable within max_snap_meters (default 2000). Usually the coordinate is not in the area you named, and the message says which area does contain it — re-run against that one rather than raising the ceiling.

BEYOND_RANGE — a route exists but is longer than the mode allows. Walking is capped (max_walk_meters, default 10,000, max 25,000). Raise the cap or use profile: "car".

NO_ISOCHRONE — reachability was asked for over the driving graph. It is walking-only, and this refuses rather than returning a search space that looks like a reachable set. For driving, name destinations and use drive_times.

REACH_TOO_LARGEmax_walk_meters above the 5 km reachability cap. Lower it, or use route with profile: "foot" for one long trip.

NO_PLACE_NEARBY — from reverse_geocode, nothing named within the radius; open water and wilderness genuinely have no answer, otherwise raise max_meters (widening is cheap — the search starts at 30 m). From geocode, nothing matched the text: house numbers match exactly, and OSM has roughly a quarter of US house numbers, so retry without the number for a street-level answer. A named feature needs at least 3 characters to be searched at all. When most — not all — of a name's words match something, geocode returns it flagged partial_name: true instead of failing; a query that still gets this error shares too little with anything indexed for even a flagged guess. geocode searches one area at a time, so a place that plainly exists but is not found is often in another area — list_areas with the name as filter reports which one holds it.

Runtime

PAYLOAD_TOO_LARGE — the exported payload exceeded the size cap after JSON encoding. Aggregate, slice, or project inside the script — counts, a tag histogram, the top N — instead of the full result set.

PAYLOAD_NOT_SERIALIZABLE — the payload holds a function, undefined, or a circular reference. A Result's name/asBound/asPoint/asFeature are methods: call them.

UNKNOWN_PROPERTY — the script read a property a Result does not have (r.lat exists; r.minLat and r.center do not). In plain goja that read would return undefined and flow NaNs silently into the payload; a Result throws instead, and the error carries the full roster of properties and methods plus a did-you-mean. Feature-test with ("x" in r) — the in operator never throws. Tag values are exempt: r.tags.anything is an ordinary object access and undefined for an absent tag is normal.

Zillow

ZILLOW_BAD_INPUT — empty bounding_boxes, or a box that is not exactly [minLat, minLon, maxLat, maxLon]. Latitude first — this tool is the exception.

ZILLOW_UPSTREAM — the upstream request failed or returned an unexpected shape. Usually transient: retry, or narrow the boxes.

Correction loop

  1. Call the tool.
  2. If the response starts with <CODE>:, branch on the code.
  3. AREA_NOT_FOUND — retry with the closest candidate, or list_areas.
  4. SYNTAX_INVALID / INVALID_JSON — reread knowhere://docs/query.
  5. INVALID_COORDINATES / INVALID_BOUNDING_BOX — check [lon, lat] order and range.
  6. QUERY_TIMEOUT / QUERY_TOO_LONG / TOO_MANY_RESULTS — narrow, or use tag_values to find a more selective filter; for a count alone use query.count().
  7. NO_ROUTE / NO_ROAD_NEARBY — check both ends are in the same area; NO_ROUTING_DATA — fall back to near.
  8. PAYLOAD_TOO_LARGE — export less.