examples · ask · 6 / 6
6. When the compiler can't make a plan
← Ask exampleswhat this does
Send a question the compiler can't make sense of. Instead of guessing, the engine returns a 400 with a structured body: a stable error code (no_plan_compiled), a human-readable hint explaining why, and a suggested rephrase that uses identifiers actually present in your schemas.
when this happens
- The question doesn't contain any recognisable table, column, or relation name.
- The question is ambiguous in a way the compiler can't resolve - two equally-good schemas match and there's no hint to break the tie.
- The question implies a feature that isn't supported (e.g. recursive CTEs, full-text search) - you'll get
no_plan_compiledwith a hint pointing at the unsupported feature.
Show the suggested rephrase in your UI when you have one. It's grounded in the user's actual schemas, not boilerplate.
the request
POST /v1/tenants/:t/ask
curl -X POST "https://$OC_HOST/v1/tenants/$OC_TENANT/ask" \
-H "Authorization: Bearer $OC_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "nl": "ufnwiefwn wefjwe" }'try:
db.ask("ufnwiefwn wefjwe")
except OriginChainError as e:
print(e.status) # 400
print(e.code) # "no_plan_compiled"
print(e.hint)
print(e.suggested_rephrase)try {
await db.ask("ufnwiefwn wefjwe");
} catch (e) {
if (e.status === 400 && e.code === "no_plan_compiled") {
console.log(e.hint);
console.log(e.suggested_rephrase);
}
}_, err := db.Ask(ctx, "ufnwiefwn wefjwe")
if err != nil {
var apiErr *originchain.APIError
if errors.As(err, &apiErr) && apiErr.Code == "no_plan_compiled" {
fmt.Println(apiErr.Hint)
fmt.Println(apiErr.SuggestedRephrase)
}
} what you get back
HTTP/1.1 400 Bad Request
{
"error": "no_plan_compiled",
"hint": "the question contained no recognisable identifiers (table, column, or relation name). nothing in the registered schemas matched any token.",
"suggested_rephrase": "ask in terms of names that appear in your schemas - e.g. \"how many shop.customers do I have\""
} error is stable - branch on it in your code. hint and suggested_rephrase are human-readable and may change wording between releases; show them, don't parse them.
how it works
- The compiler tokenises the question and tries to bind tokens to schema identifiers (namespace, table, column, relation name).
- If too few tokens bind, the compiler refuses to guess. There is no silent fallback to "scan everything".
- The hint explains the binding failure in human terms; the suggested rephrase uses identifiers from the visible catalog as anchor words.
- A failed compile is not cached - retry safely with a better question.
common mistakes
- Ambiguous column references. "Total by month" with no date column anywhere in the visible schemas is unanchored - say which column to bucket by.
- Sensitive data in questions. The LLM-fallback path (if configured) sees the full question. Don't put PII, secrets, or credentials in the
nlfield - bind those as parameters in/v1/queryinstead. - Retrying without rephrasing. The error is deterministic for a fixed schema set. Retrying the same question gets the same error. Either rephrase or change the schemas list (or registered schemas).