---
title: "Error codes"
locale: en
url: https://tlg.builera.app/en/docs/reference/errors
verified: 2026-10-24
app_version: "2.0"
generated: true
---

# Error codes

Every REST v2 / MCP error code: meaning, HTTP status, whether to retry and what to do.

Errors come back as problem JSON (RFC 9457): `type`, `title`, `status`, `code`, `detail`, `retryable`, and sometimes `retry_at`, `hint`. Agents decide on `code`, never on the wording of `detail`.

## Request

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `invalid_key` | 401 | No | The connection key is missing or wrong, or the connection was stopped / revoked. | Send `Authorization: Bearer tga_…`; if the key leaked or was lost, create a new one in Settings → AI connections. |
| `invalid_json` | 400 | No | The request body is not valid JSON. | Send `Content-Type: application/json` with a JSON object. |
| `method_not_allowed` | 405 | No | Wrong HTTP method for this address. | Operations use `POST /ops/<code>`; listings use `GET`. |
| `unknown_operation` | 404 | No | No operation has this code. | See the REST reference or call `GET /ops`. |
| `not_found` | 404 | No | The object doesn't exist, or this connection may not see it. | Check the ID and the accounts assigned to the connection. |
| `idempotency_key_required` | 400 | No | This operation has effects and needs an `Idempotency-Key` header. | Send one unique key per logical action; resend the same key when retrying. |
| `invalid_idempotency_key` | 400 | No | The `Idempotency-Key` has the wrong format. | Use a 1–100 character string such as a UUID. |
| `invalid_batch` | 422 | No | The batch is invalid (empty, too long or malformed). | Send a list of `{ op, input }` as described for `/batch`. |
| `rate_limited` | 429 | Yes | The connection sent more requests per minute than allowed. | Wait until `retry_at` and resend; the limit can be raised in the connection settings. |

## Permissions

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `scope_denied` | 403 | No | The connection lacks the scope this operation needs. | Ask the workspace owner to add the scope named in `detail`. |
| `role_denied` | 403 | No | The connection's role is not enough for this operation. | Raise the connection's role (never above its creator's). |
| `creator_gone` | 403 | No | The person who created the connection left the workspace, so it lost its rights. | A current member must create a new connection. |
| `forbidden_by_policy` | 403 | No | The connection's policy forbids this kind of dangerous action. | Change the dangerous-action policy in the connection settings if really needed. |
| `forbidden` | 403 | No | Refused for lack of permission. | Check the connection's role and scopes. |
| `account_denied` | 403 | No | The operation touches a Telegram account not assigned to the connection. | Use only accounts listed by `whoami`, or ask the owner to assign more. |
| `needs_all_accounts` | 403 | No | This work (nodes, proxies, workspace-wide jobs) needs a connection assigned every account. | Use a connection with access to all accounts. |
| `scope_exceeds_owner` | 403 | No | A connection cannot get more rights than the person who created it. | Remove the scopes its creator does not have. |

## Person's confirmation

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `confirmation_required` | 409 | No | A dangerous action needs the person's approval before it runs. | Show `summary` to the person; only if they agree, call again with the same input plus `confirm_token`. |
| `confirmation_missing` | 403 | No | The confirmation token is wrong or doesn't exist. | Call again without a token to get a fresh confirmation request. |
| `confirmation_mismatch` | 403 | No | The token was issued for a different action (the input changed). | Resend exactly the approved input, or ask for a new confirmation. |
| `confirmation_expired` | 403 | No | The confirmation token expired. | Ask the person to confirm again. |
| `confirmation_denied` | 403 | No | The person declined this action. | Don't retry; ask the person what they want instead. |
| `confirmation_used` | 403 | No | The confirmation token was already used once. | Each approval allows one run; ask again to run it again. |
| `plan_not_found` | 422 | No | The prepared plan was not found. | Prepare the plan again, then apply it. |
| `plan_expired` | 422 | No | The prepared plan expired. | Prepare the plan again. |
| `plan_used` | 422 | No | The plan was already applied. | Read the current configuration instead of applying it twice. |
| `plan_mismatch` | 422 | No | The configuration changed after the plan was prepared. | Prepare the plan again on the new configuration. |

## Connection budget

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `budget_exhausted` | 429 | Yes | The connection used up today's budget for this kind of work. | Wait until `retry_at`, or ask the owner to raise the connection's budget. |
| `budget_unavailable` | 503 | Yes | The budget couldn't be checked, so the write is held (fail closed). | Retry after `retry_at`. |

## Conflicts

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `idempotency_mismatch` | 409 | No | Same `Idempotency-Key` with different input than the first request. | Use a new key for a new action; reuse a key only to resend the same action. |
| `idempotency_in_progress` | 409 | Yes | The first request with this key is still running. | Wait a moment and resend with the same key to get the first answer. |
| `idempotency_conflict` | 409 | No | The idempotency key couldn't be held (concurrent write). | Resend with the same key shortly. |
| `conversation_locked` | 409 | Yes | Another person or connection holds this conversation. | Wait for the lock to expire, or ask its holder to release it. |
| `revision_conflict` | 409 | No | Someone else changed the configuration first. | Read the latest version and apply your change to it. |
| `stale_conversation` | 409 | No | The conversation got new messages since the connection last read it. | Read the new messages, then decide whether to reply. |
| `loop_suspected` | 429 | Yes | Sending paused because it looks like an auto-reply loop. | Check your automation rules / agent; retry after `until`. |

## Input

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `invalid_input` | 422 | No | The input doesn't match the operation's schema. | See `issues` in the answer and the fields in the operation reference. |
| `invalid_cursor` | 422 | No | The event cursor is invalid. | Use the `cursor` returned last time, or leave it empty to start over. |
| `invalid_type` | 422 | No | The filter names an event type that doesn't exist. | Use the names in the events reference. |
| `invalid_steps` | 422 | No | The sequence steps are invalid. | Fix the steps described in `detail` and save again. |
| `unknown_action` | 422 | No | This kind of job is no longer supported. | Use a current operation from the reference. |
| `dns_blocked` | 422 | No | The webhook address points to a private network or a blocked address. | Use a public HTTPS address. |
| `dns_failed` | 422 | Yes | The webhook's domain name couldn't be resolved. | Check DNS and try again. |

## System state

| Code | HTTP | Retryable | Meaning | What to do |
| --- | --- | --- | --- | --- |
| `rejected` | 422 | No | The server refused this action (reason in `detail`). | Read `detail`, fix the cause and try again. |
| `frozen` | 422 | No | The object is locked for editing (running or archived). | Stop it or create a new version, then edit. |
| `account_gone` | 422 | No | The Telegram account of this job no longer exists. | Choose another account. |
| `webhook_suspended` | 403 | No | The webhook is paused. | Resume it once the receiver works again. |
| `events_unavailable` | 422 | Yes | The event ledger can't be read right now. | Try again shortly. |
| `enqueue_failed` | 422 | Yes | The job couldn't be queued. | Try again; if it repeats, check the Alerts page. |
| `bot_unauthorized` | 422 | No | The bot token is no longer valid. | Get a new token through @BotFather from the account that made the bot. |
| `bot_update_failed` | 422 | Yes | Telegram didn't accept the bot profile change yet. | Try again shortly. |
| `error` | 422 | Yes | Unexpected error while running the operation. | Try again; if it persists, send the `operation_id` to an administrator. |
