Skip to content

BI error codes

The BI endpoints carry their own code vocabulary on top of the shared one. Every code below resolves here, which is why a BI error’s docs_url points at this page rather than a per-code one — only not_found and internal_error are shared with the rest of the API and have pages of their own.

Every BI error uses the structured envelope, on every response, regardless of the Accept header you send:

{
"error": {
"code": "feature_disabled",
"message": "SQL console is not enabled for this organization",
"docs_url": "https://docs.justcrawl.io/guides/errors/bi",
"request_id": "req_01HF3JKB9Q2W4X"
}
}
Code Status What it means What to do
feature_disabled 403 The SQL console is not enabled for your organization. Fires on every BI route before any handler runs. The likeliest first response for a new integration. Ask support to enable BI for your org.
no_org 403 Your token carries no organization. Complete onboarding, or use a key issued under an org.
no_user 403 The request has an org but no user identity. Only reachable on export requests. Use a user-scoped token rather than an org-only one.
insufficient_permissions 403 Your role lacks bi:read or bi:write; the missing permission is listed in missing. Ask an org administrator to grant the permission or assign a suitable role.
email_not_verified 403 A BI write was attempted before the user’s email was verified. Verify the account email, then retry unchanged.
authentication_required 403 A verified-email BI write reached the gateway without a user identity. Authenticate with a user-scoped token.
user_not_found 403 The authenticated user no longer exists. Sign in again or issue a key from an active user.
rls_denied 403 The query tried to read data outside your tenant. Reference only tables listed by GET /api/v1/bi/schema.
kill_switched 403 An operator has paused query execution platform-wide. Retry later; contact support if it persists.
Code Status What it means What to do
invalid_query_input 400 A query submission supplied both sql and definition, or neither. Send exactly one query form.
invalid_definition 400 A structured definition is malformed or names something outside the authorized catalog. Rediscover the schema, then rebuild the definition from returned names and supported operators.
invalid_sql 400 sql is missing, not a string, or over 100,000 characters. Send a non-empty string within the limit.
syntax_error 400 The engine rejected your SQL. The message carries the engine’s own parse detail, including position — this is the one place raw engine text is passed through, because it describes SQL you wrote. Fix the statement and resubmit.
invalid_label 400 label is not a string, or over 200 characters. Shorten it or omit it.
invalid_idempotency_key 400 Idempotency-Key is present but is not a UUID. Generate one UUID per intended query run and reuse it only when retrying that run.
invalid_submission_key 400 The query-history submissionKey filter is not a UUID. Use the UUID sent as the original query’s Idempotency-Key to recover its retained handle.
invalid_execution_context 400 sourceQueryId is malformed or was supplied without a SQL edit, or a request tried to provide server-owned scope/dialect fields. Send an owned query UUID only alongside edited sql; never send scope or dialect fields.
invalid_table_name 400 The table name in the path is not a valid identifier. Use a name exactly as returned by GET /api/v1/bi/schema.
statement_timeout 504 The query exceeded the time limit. The limit that applied is reported as maxQuerySec by the result manifest. Narrow the range, add a WHERE, or aggregate server-side.
Code Status What it means What to do
not_found 404 No such query, export, or saved query in your organization. Not-yours and not-exists are deliberately indistinguishable so cross-tenant ids cannot be probed. Check the id and the org the token belongs to.
not_ready 409 The query has not reached success yet. The body carries the current status as a sibling of error. Poll GET /api/v1/bi/queries/{id} until it is terminal.
idempotency_conflict 409 This organization already used the supplied Idempotency-Key for a different user, SQL, label, source query, or agent scope. Do not retry with that key. Generate a new UUID for a genuinely new run, or resend the original request unchanged.
too_many_queries 429 Your organization’s concurrency or queue-depth cap is full. No Retry-After header is sent — back off with capped exponential retry.
canceled 409 The query was canceled before it finished. Resubmit if you still want the result.
transient 409 An engine or network blip unrelated to your SQL. Retry; this one is expected to succeed on a second attempt.
Code Status What it means What to do
invalid_name 400 name is missing, not a string, or over 120 characters. Send a non-empty name within the limit.
invalid_description 400 description is not a string or null, or is over 1,000 characters. Send a string, or null to clear it.
invalid_body 400 A PATCH arrived with no updatable field. Include at least one of name, sql, description, chartConfig.
invalid_saved_query_input 400 Saved-query creation supplied both sql and sourceQueryId, or neither. Send exactly one source form.
invalid_source_query 400 sourceQueryId is not a UUID. Send the id of a completed query in your organization.
invalid_cursor 400 The saved-query list cursor is malformed or no longer decodes to a valid position. Restart pagination without a cursor.
invalid_chart_config 422 chartConfig is present but malformed. 422 rather than 400 so a broken chart payload is distinguishable from a missing name or sql. Send {type, x, y} where type is bar, line, or pie; pie takes a single y.
saved_query_name_taken 409 Another saved query in your org already has that name. Pick a different name.
source_query_not_executable 409 The source query is not complete or has no valid immutable execution scope. Wait for completion and save that run; legacy unknown-scope rows cannot be promoted.
saved_query_not_executable 409 The saved object has no executable content with a proven immutable scope. Recreate it from a completed query or contact support if it predates scoped saves.
not_structured 409 SQL conversion was requested for a saved query that is already editable SQL. Edit the existing SQL directly.
conversion_unavailable 409 The stored definition no longer resolves against the current authorized catalog. Rediscover the schema and rerun or recreate the structured query.
has_active_schedules 409 The saved query has enabled schedules attached, which block deletion. The blocking names are in error.schedules — inside the error object, not beside it. Disabled schedules do not block and are removed along with the query. Disable or delete the named schedules, then retry.
Code Status What it means What to do
invalid_format 400 format is not csv or parquet. Send one of the two.
result_too_large 400 The result exceeds the export row cap. rowCount and maxRowCount are siblings of error, not members of it. Narrow the query with LIMIT or WHERE and re-run before exporting.
enqueue_failed 500 The export row was created but could not be queued. Retry the export request.

These are not HTTP errors. An export that cannot be delivered ends with status: "failed", and GET /api/v1/bi/exports/{exportId} returns one of these codes in errorCode, with customer-safe text in errorMessage. The response keeps both the export id and its source query id.

errorCode What it means What to do
source_unavailable The source query’s stored results no longer exist, for example after they expire. Re-run the source query, then export the new run.
source_malformed The source query’s stored results are incomplete or could not be read back. Re-run the source query and export the new run. Contact support with the export id if it recurs.
source_too_large The stored result is larger than the export size limit, which is checked while the file is built. Narrow the query with LIMIT, WHERE, or fewer columns, re-run it, then export.
source_read_failed Reading the stored results failed for a reason unrelated to your query. Request the export again.
upload_failed Writing the finished file to storage failed. Uploads are retried automatically before an export fails. Request the export again.
encoding_error The rows could not be encoded as CSV or Parquet. Try the other format, or cast unusual column types to text in the query and re-run it.
retry_exhausted Every attempt failed on a temporary error, and the export ran out of retries. Request a new export later. Contact support with the export id if it keeps happening.
Code Status What it means What to do
invalid_saved_query_id 422 savedQueryId is missing. Supply the saved query to schedule.
saved_query_not_found 422 The referenced saved query does not exist in your org. Check the id.
invalid_frequency 422 frequency is not one of the accepted values. Use a supported frequency.
invalid_cron 422 cronExpr is missing for a custom frequency, or is not a valid expression. Supply a valid 5-field cron expression.
invalid_timezone 422 timezone is not a string. Send an IANA timezone name.
invalid_is_enabled 422 isEnabled is not a boolean. Send true or false.
interval_too_short 422 The schedule would fire more often than the 15-minute floor. Widen the interval.
max_schedules_reached 422 Your organization is at its schedule limit. Delete a schedule, or contact support to raise the cap.
Code Status What it means What to do
internal_error 500 Something failed on our side. The detail is in our logs, never in the response. Retry once, then contact support with the request_id.

Every BI error carries a request_id, identical to the X-Request-ID response header. Quote either one to support and we can find the exact request.