---
title: "Error Codes & Troubleshooting"
description: "Plan and quota responses, plus every run-failure error code on Datarelix: what each one means and the exact action that clears it."
canonical: https://docs.datarelix.ai/api/errors/
---

# Error Codes & Troubleshooting

There are two families of errors here, and they behave differently.

**Plan and quota responses** come back from the HTTP request itself, before or instead of a run. They carry a JSON body with a `code` field, and each one has a specific action that clears it. These are the ones a new account meets first, so they come first below.

**Run failures** happen inside a run that was accepted and started. They arrive as an `error` event on the stream (or on the finished run) with an `error_code`, and they're grouped into five recovery classes.

## Plan and quota responses

When a request is refused for plan reasons, the response body is a JSON object with a `code`. **Branch on `code`, never on the HTTP status alone** — `429` is shared between the rate limiter (which returns a plain string) and the quota system (which returns one of these objects), and `402` is shared by several distinct situations.

| Code | Status | What happened | What clears it |
| --- | --- | --- | --- |
| `quota_exceeded` (`scope: "month"`) | `429` | You've used every question your plan includes this calendar month. The body carries `limit`, `used`, and `resets_at`. | Wait for the counter to reset at 00:00 UTC on the 1st of next month, or upgrade — the new allowance applies immediately. On a Team plan the pool is shared across the workspace, so more seats also raise it. |
| `quota_exceeded` (`scope: "day"`) | `429` | Pro and Team carry a per-person fair-use ceiling of 500 questions per day. The body carries `resets_at`. | Wait for the ceiling to reset at midnight UTC. Your monthly allowance is untouched. |
| `discovery_limit` | `429` | You've used every AI schema analysis your plan includes this month. The body carries `limit`, `used`, and `resets_at`. | Wait for the monthly reset, or upgrade. Re-running structure-only discovery, resuming a checkpointed analysis, and retrying one that reuses existing introspection are all free — only a fresh schema analysis counts. |
| `connection_limit` | `402` | Creating, duplicating, or activating a connection would exceed your plan's active-connection limit. With `reason: "over_limit"`, it means you already hold more active connections than your plan allows — typically after a downgrade — and questions are blocked until you're back under it. | Pause a connection you don't need right now (Connections page, or `POST /api/v1/connections/{id}/paused`), or upgrade. Pausing keeps the connection's schema analysis and history. |
| `connection_paused` | `402` | The connection this request targets is paused. Paused connections can't run questions or schema discovery. | Activate it from the Connections page — which needs room under your connection limit — or target a different connection. |
| `seats_full` | `409` | An invite would exceed the seats on the Team subscription, or the workspace filled up between the invite being sent and accepted. The body carries `seats` and `members`. | Add seats in the Stripe customer portal, or remove a member or a pending invite, then re-send. |
| `team_min_seats` | `422` | A Team checkout was requested with fewer than 2 seats. | Check out with at least 2 seats, or pick Lite or Pro for a single user. |
| `plan_blocked` | `402` | An action that requires an active Team subscription was attempted without one — inviting teammates is the case you'll actually meet. | Start or restore a Team subscription. Note this code never means your account is suspended: an expired trial or a cancelled subscription lands you on the Free plan with your data intact, not in a blocked state. |

Two things worth knowing about quota counting:

- Counters increment when a request is **accepted**, so a run that then fails still consumes a question.
- If the counter store is briefly unavailable, requests are allowed through rather than refused.

Plan limits themselves — how many questions, connections, and AI schema analyses each plan includes — are in [Billing & plans](/guides/billing/).

## Run failures

Once a run has started, failures are classified into five **classes** for recovery UX:

- **NO_RESULTS** — the question was understood but produced no useful data.
- **TIMEOUT** — execution exceeded its time limit.
- **PLAN_FAILURE** — the model could not produce a valid plan.
- **CONNECTION_FAILURE** — the database could not be reached.
- **INTERNAL** — generated SQL/code was invalid, the sandbox crashed, or the model returned malformed output.

Every error event in the run stream carries an `error_code` that maps to one class.

### NO_RESULTS

| Code | Meaning | Recovery |
|------|---------|----------|
| `MISSING_TABLE` | Generated SQL references a table not in scope | Add the missing table to scope and retry. |
| `MISSING_COLUMN` | Generated SQL references a column that doesn't exist | Check your table selection or rephrase. |
| `TYPE_MISMATCH` | Implicit cast failed | Rephrase to avoid mixing incompatible types. |

The frontend surfaces these as "broaden your question" suggestions.

### TIMEOUT

| Code | Meaning | Recovery |
|------|---------|----------|
| `SQL_TIMEOUT` | Database query exceeded the query time limit (30 seconds) | Add date filters or narrow scope. |
| `SANDBOX_TIMEOUT` | Sandbox Python step exceeded its wall-clock cap (90 seconds) | Simpler analysis, or reduce the data volume it works on. |

### PLAN_FAILURE

| Code | Meaning | Recovery |
|------|---------|----------|
| `NOT_ANSWERABLE` | The model determined the question can't be resolved with the data in scope | Rephrase, or bring the missing tables into scope. |
| `AMBIGUOUS_QUERY` | Multiple valid interpretations | Be more specific. |

The frontend offers an editable retry — your question stays in the input ready to revise.

### CONNECTION_FAILURE

| Code | Meaning | Recovery |
|------|---------|----------|
| `CONNECTION_ERROR` | Database unreachable | Test from sidebar; check credentials. |

The frontend's recovery banner has a "test connection" button.

### INTERNAL

| Code | Meaning |
|------|---------|
| `SQL_SYNTAX` | Generated SQL didn't parse |
| `SQL_VALIDATION` | Generated SQL failed our validation rules |
| `SQL_EXECUTION` | Database returned an error |
| `SANDBOX_CODE_ERROR` | Python in the sandbox raised |
| `SANDBOX_OOM` | Python in the sandbox exceeded memory cap |
| `LLM_INVALID_OUTPUT` | The model returned a plan that didn't match the required structure |

Most of these trigger an automatic revise-and-retry, within strict limits. Once that budget is exhausted you see the underlying error.

## Related

- [Billing & plans](/guides/billing/) — what each plan includes and how pausing a connection frees a slot.
- [REST API reference](/api/rest/) — the endpoints these responses come from.
- [Security](/guides/security/) — why some questions are refused before they run.
