Errors & status codes
The error envelope
Section titled “The error envelope”Every non-200 response uses one envelope:
{ "request_id": "01HV...", "error": { "code": "E2001", "severity": "error", "message": "Access denied for this operation", "object": { "kind": "Metric", "name": "arr" }, "hint": "Contact policy author. Use request_id for support." }}Always log the request_id — it ties the response to the immutable audit entry
and any lineage events.
Code bands
Section titled “Code bands”| Band | Meaning | Typical HTTP |
|---|---|---|
E0xxx |
Schema / malformed request | 400 |
E1xxx |
Resolve — valid request, can’t be resolved (e.g. metric/facet unknown) | 422 |
E2xxx |
Policy — PDP deny or fail-closed | 403 / 503 |
E3xxx |
Engine internals | 401 / 500 |
Commonly seen codes
Section titled “Commonly seen codes”| Code | HTTP | Condition |
|---|---|---|
E0501 |
400 |
Empty keys — no full-scan allowed (joint/resolve, traverse) |
E0502 / E0259 |
400 |
Anchor/target not declared or not reachable (traverse) |
E0511 |
400 |
Out-of-grammar / non-SELECT / doesn’t lower to an IR node (query) |
E0512 |
403 |
Non-declared object / outside the tenant allowlist (query) |
E0513 |
400 |
Body mixes osql with sql or MetricFlow fields (query) |
E0514 |
400 |
JOIN … ON is not a sealed-entity-key equijoin — R3 firewall (query) |
E0515 |
403 |
Cross-modal join key not cleartext for the subject — fail-closed (query) |
E0521 |
503 |
Decoder projection op (e.g. SUMMARIZE) but no LLM backend (query) |
E0522 |
400 |
Generative op output failed validation (query) |
E0510 |
502 |
Trino execution failure (query) |
E2001 |
403/503 |
PDP deny (non-revealing) / PDP snapshot missing (fail-closed) |
E2101 / E2102 |
403 |
PEP deny — out of scope / blocking obligation |
E3001 |
401 |
Invalid or expired token |
E0503 |
502 |
Control-plane guard — semantic engine unreachable (managed tier proxy, not an engine code) |
The canonical, exhaustive error model lives in the specification §9.