# Errorgram documentation Canonical site: https://errorgram.rmbk.me/ Catalogue 0.1.0 · schema 1.0.0 · reviewed 2026-09-16. # Telegram errors, explained. Canonical page: https://errorgram.rmbk.me/ One `BadRequest` can mean an unchanged message, a missing chat, or a request that needs a new chat ID. Your bot needs to tell them apart. **Errorgram gives each supported condition a stable name.** One open JSON catalogue powers the reference, Python and TypeScript bindings, and opt-in aiogram and grammY adapters. ## Find the error in front of you Search by Telegram's response text, a condition ID, or a framework exception name. Each condition has its own page with an example, possible causes, diagnostic limits, and pinned source evidence. | Telegram says… | Start here | | --- | --- | | `Bad Request: chat not found` | [chat.not_found](https://errorgram.rmbk.me/errors/chat.not_found/) | | `Bad Request: message is not modified…` | [message.not_modified](https://errorgram.rmbk.me/errors/message.not_modified/) | | `Too Many Requests: retry after…` | [request.retry_after](https://errorgram.rmbk.me/errors/request.retry_after/) | | `Forbidden: bot was blocked by the user` | [bot.blocked_by_user](https://errorgram.rmbk.me/errors/bot.blocked_by_user/) | [Try your response in the playground →](https://errorgram.rmbk.me/playground/) · [Browse every condition →](https://errorgram.rmbk.me/catalogue/) ## Give your handler something precise ```python from errorgram import classify failure = classify({ "ok": False, "error_code": 400, "description": "Bad Request: chat not found", }) if failure.id == "chat.not_found": print("Check the chat ID and the bot's access.") ``` The same IDs work across languages, logs, metrics, and documentation. Your application keeps control of retries, delivery, and state changes. | Build with | What you get | | --- | --- | | [Python & aiogram](https://errorgram.rmbk.me/python/) | Plain response classification and concrete exception types. | | [JavaScript, TypeScript & grammY](https://errorgram.rmbk.me/javascript/) | ESM bindings, typed facts, and framework-compatible enrichment. | | [JSON & AI agents](https://errorgram.rmbk.me/agents/) | The complete catalogue, schema, and plain Markdown reference. | ## Know what the evidence supports The catalogue tracks Bot API **10.3**. Seven conditions also have recorded live observations. Examples use synthetic data; each record links to its evidence. Coverage is incomplete and grows through reviewed contributions. A stable ID describes the observed condition. It cannot prove every underlying cause. Unknown responses stay unknown, and transport failures and framework validation errors remain outside the catalogue. [Get started](https://errorgram.rmbk.me/getting-started/) · [How matching works](https://errorgram.rmbk.me/matching/) · [Read this page as Markdown](https://errorgram.rmbk.me/index.md) --- # Get started Canonical page: https://errorgram.rmbk.me/getting-started/ Start with a raw Telegram error response. Add a stable condition ID, then decide how your application should handle it. Errorgram is at **0.1.0**. Packages are available from this repository; npm and PyPI releases have not been published yet. ## Build from source The checked-in toolchain uses Python **3.14.7**, Node **26.8.2**, npm **12.0.2**, and [uv](https://docs.astral.sh/uv/getting-started/installation/) **0.12.15**. Dependency versions are locked. ```sh git clone https://github.com/uburuntu/errorgram.git cd errorgram make setup make check make build ``` The build writes a Python wheel, a source distribution, and an npm tarball to `dist/`. ## Python From the checkout, install the core package into an environment: ```sh uv venv uv pip install -e . ``` ```python from errorgram import classify result = classify({ "ok": False, "error_code": 400, "description": "Bad Request: chat not found", }, method="sendMessage") assert result.id == "chat.not_found" ``` Use `uv pip install -e '.[aiogram]'` to include aiogram. See [Python & aiogram](https://errorgram.rmbk.me/python/) for concrete exceptions and adapter behavior. ## JavaScript and TypeScript After building, install the tarball in your bot project: ```sh npm install /path/to/errorgram/dist/errorgram-0.1.0.tgz ``` ```ts import { classify } from "errorgram"; const result = classify({ ok: false, error_code: 400, description: "Bad Request: chat not found", }, { method: "sendMessage" }); if (result.status === "matched") { console.log(result.id, result.entry.summary); } ``` The package includes ESM JavaScript and TypeScript declarations. The core has no runtime dependencies. See [JavaScript & grammY](https://errorgram.rmbk.me/javascript/) for the optional framework adapter. ## Choose a small first integration Add `result.id` and `result.status` to your existing diagnostics. Once you understand the condition and its limits, use the ID in the part of your application that owns the handling decision. Pass the API method when available. Keep your existing fallback for an `unknown`, `ambiguous`, or `insufficient_context` result. Read [how matching works](https://errorgram.rmbk.me/matching/) before using a classification to branch. [Read this page as Markdown](https://errorgram.rmbk.me/getting-started.md) --- # Try a Bot API response Canonical page: https://errorgram.rmbk.me/playground/ ## How to use the playground Paste the JSON response body and choose **Classify response**. The API method is optional; add it when a result needs more context. **Load example** inserts a synthetic catalogue response. **Clear** removes your input and result. The [interactive form](https://errorgram.rmbk.me/playground/) runs the Errorgram JavaScript classifier in your browser. No bot token is needed. For example, this response matches [request.retry_after](https://errorgram.rmbk.me/errors/request.retry_after/) and extracts `retry_after: 5`: ```json { "ok": false, "error_code": 429, "description": "Too Many Requests: retry after 5", "parameters": { "retry_after": 5 } } ``` ## Read the result | Status | Meaning | | --- | --- | | `matched` | One condition matches. Read its ID, summary, extracted facts, and linked reference. | | `unknown` | The response is an API error, but the catalogue has no matching rule. | | `insufficient_context` | A potential match requires the API method. Add it and try again. | | `ambiguous` | Competing matches or conflicting parameters prevent a single result. | | `not_api_error` | The JSON does not have the Bot API error-response shape. | The form accepts up to 32,768 characters and explains invalid JSON before classification. Empty facts, `{}`, means no values were extracted. A condition identifies what the response establishes, not every underlying cause. Each record states its evidence. Coverage is incomplete. ## Privacy and reporting Your response and method are never uploaded, logged, or saved by this page, and are cleared when you leave. Classification requires JavaScript; the guide and reference do not. For an unknown error, [open the empty GitHub form](https://github.com/uburuntu/errorgram/issues/new?template=unknown-error.yml). Your input is never copied into it. Reports are public: remove tokens, token-bearing URLs, private identifiers, and message content before sharing. Include the method and whether your example is live, synthetic, or source-derived. [How matching works](https://errorgram.rmbk.me/matching/) · [Contribute a condition](https://errorgram.rmbk.me/contributing/) · [Read this page as Markdown](https://errorgram.rmbk.me/playground.md) --- # Python & aiogram Canonical page: https://errorgram.rmbk.me/python/ A `400` groups many failures together. Errorgram names the condition while keeping the response and your handling decisions intact. From a [local checkout](https://errorgram.rmbk.me/getting-started/), run `uv venv` and `uv pip install -e .`. Use `uv pip install -e '.[aiogram]'` to include aiogram. The core has no runtime dependencies. ## Read a response ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: chat not found", } result = classify(response, method="sendMessage") assert result.id == "chat.not_found" assert result.response is response print(result.entry["summary"]) ``` Only `matched` results have an ID and entry. Other statuses are `unknown`, `ambiguous`, `insufficient_context`, and `not_api_error`. Candidate IDs explain ambiguous results or missing method context. `facts` contains extracted values such as `retry_after`. `catalogue()` returns a fresh copy of the catalogue and its evidence sources. `CATALOGUE_VERSION` identifies the data version; `ConditionId` and `CONDITION_IDS` expose its stable IDs. Each classification includes the catalogue version and an independent snapshot of the matched entry. ## Use concrete exceptions ```python from errorgram import ApiError, ChatNotFound, to_exception error = to_exception(response, method="sendMessage") assert isinstance(error, ChatNotFound) assert isinstance(error, ApiError) assert error.response is response ``` `to_exception()` creates an exception without raising it. Unclassified API failures use `ApiError`; inputs outside the Bot API error envelope return `None`. Every exception carries its `classification`, `id`, and `facts`. Each [condition page](https://errorgram.rmbk.me/catalogue/) lists its generated Python type. ## Add aiogram details Enrichment is explicit. Keep your existing `TelegramBadRequest` catches, or catch a generated subtype such as `errorgram.aiogram.MessageNotModified`. ```python from aiogram.exceptions import TelegramAPIError from errorgram.aiogram import enrich async def edit_message(bot, chat_id, message_id, text): try: return await bot.edit_message_text( text=text, chat_id=chat_id, message_id=message_id ) except TelegramAPIError as original: error = enrich(original) if error is original: raise raise error from original ``` The enriched exception keeps the original message, method, recovery parameters, and catch compatibility. It adds `classification`, `id`, `facts`, `original`, and `fidelity`. Unknown conditions and transport exceptions pass through unchanged. Repeated enrichment returns the same object. Enrichment never retries, suppresses exceptions, updates chat IDs, or registers handlers. ## Understand framework fidelity aiogram discards the wire error code and some response fields. Errorgram labels the information it can reconstruct: | Field | What to expect | | --- | --- | | `response` | Reconstructed from the exception. | | `error_code` | Inferred from the framework exception type and supported rules. | | `description` | Retry and migration descriptions are marked `framework_modified`. | | `parameters` | Always marked `partial`. | Use `classify()` on the raw response when exact wire evidence matters. The original aiogram exception remains available as `original`. [How matching works](https://errorgram.rmbk.me/matching/) · [Read this page as Markdown](https://errorgram.rmbk.me/python.md) --- # JavaScript & grammY Canonical page: https://errorgram.rmbk.me/javascript/ Give a Telegram response a stable identity, with TypeScript facts that narrow alongside the condition ID. The package ships ESM JavaScript and TypeScript declarations. [Build from the repository](https://errorgram.rmbk.me/getting-started/), then install `dist/errorgram-0.1.0.tgz` in your bot project. The core has no runtime dependencies. ## Classify a response Pass the error body to `classify`. Include the API method when available: some responses need that context to distinguish their meaning. ```ts import { classify } from "errorgram"; const response = { ok: false, error_code: 400, description: "Bad Request: group chat was upgraded to a supergroup chat", parameters: { migrate_to_chat_id: -1001234567890 }, }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "chat.migrated") { // TypeScript knows this fact is a number. console.log(result.facts.migrate_to_chat_id); console.log(result.entry.summary); } ``` `result.response` is the original object. `facts` contains values extracted from the response; version-specific metadata stays in `entry`. Import `catalogue` from the same package for the complete data and source references. Only `matched` results carry an ID and entry. Other statuses are `unknown`, `ambiguous`, `insufficient_context`, and `not_api_error`; see [how matching works](https://errorgram.rmbk.me/matching/) for their meaning. ## Add grammY details Install the optional framework: ```sh npm install grammy@1.46.0 ``` For strict TypeScript checks, grammY's declarations also need Node and node-fetch types: ```sh npm install --save-dev @types/node@26.5.1 @types/node-fetch@2.6.13 ``` Enrich errors inside your existing handler: ```ts import { Bot } from "grammy"; import { enrich, EnrichedGrammyError } from "errorgram/grammy"; const bot = new Bot(process.env.BOT_TOKEN!); bot.catch(({ error }) => { const failure = enrich(error); if (failure instanceof EnrichedGrammyError) { const result = failure.classification; console.log(result.id, result.entry.summary); if (result.id === "request.retry_after") { console.log(result.facts.retry_after); // number, in seconds } } }); ``` `EnrichedGrammyError` extends `GrammyError`, so broad framework catches still work. It keeps the method, payload, description, parameters, message, and stack. The original exception is available through both `original` and `cause`. `id` and `facts` provide shortcuts to classification data. Narrow on `classification.id` for precise fact types. For a `BotError` wrapper, pass its `error` field as shown above. Unknown errors and `HttpError` pass through unchanged. Repeated enrichment returns the same object. The adapter never retries, suppresses an error, or changes bot state. ## Understand framework fidelity The `fidelity` object describes what the framework makes available: | Field | Value | Meaning | | --- | --- | --- | | `description` | `preserved` | Telegram's description remains intact. | | `parameters` | `framework_normalized` | grammY replaces missing parameters with `{}`. | | `method` | `preserved` | The method comes from the original exception. | | `response` | `reconstructed` | The adapter rebuilds the body from framework fields. | HTTP status and discarded response fields are unavailable. Use the raw response with `classify()` when you need its exact contents. [Browse the catalogue](https://errorgram.rmbk.me/catalogue/) · [Read this page as Markdown](https://errorgram.rmbk.me/javascript.md) --- # How matching works Canonical page: https://errorgram.rmbk.me/matching/ Telegram supplies a broad code and a description. Errorgram adds a condition ID when the available evidence supports one. The [JSON catalogue](https://errorgram.rmbk.me/catalogue.json) is the source of truth. Each record contains match rules, possible causes, diagnostic limits, guidance, and evidence. Generated Python and TypeScript bindings use the same records and IDs. ## Read the result | Status | Meaning | | --- | --- | | `matched` | One supported condition fits. `id` and `entry` are available. | | `unknown` | The response is an API error, but no supported condition fits safely. | | `ambiguous` | Conditions or structured signals conflict. See `candidates`. | | `insufficient_context` | A possible match needs the API method. See `candidates`. | | `not_api_error` | The input lacks a valid Bot API error envelope. | A matched ID identifies what can be observed. It does not prove one underlying cause. [chat.not_found](https://errorgram.rmbk.me/errors/chat.not_found/), for example, can result from several lookup failures. ## Match conservatively Fields within a rule are combined with AND; `match_any` combines alternatives with OR. - Codes come from the JSON response. HTTP status is separate information. - Exact descriptions preserve case and punctuation. - Templates match the whole description. Literal text is escaped; named captures accept typed ASCII digits. - API methods are compared after ASCII lowercasing. - Numeric predicates accept finite, integral values within JavaScript's safe integer range. Booleans and numeric strings do not qualify. - Valid structured parameters take precedence over description text. Malformed recovery parameters produce `unknown`; mutually exclusive signals produce `ambiguous`. - A recognized recovery parameter with an incompatible code produces `unknown`. - Competing conditions remain ambiguous. Missing context cannot silently select a competing rule. `facts` contains values extracted from the response, such as `retry_after` or an upload's byte count. Version-specific constants remain in the condition's metadata. Unknown response fields are preserved. New Telegram wording can fall back without breaking existing handlers. ## Keep framework behavior The adapters are opt-in. Known conditions gain a precise type or ID while retaining framework catch compatibility. Unknown and out-of-scope exceptions pass through unchanged. grammY retains useful response fields. aiogram can discard codes and rewrite messages. Adapters label reconstructed or inferred information and retain the original exception. For exact wire evidence, classify the raw response. Your application owns retries, suppression, and state changes. Classification itself has none of those effects. ## Read evidence and versions `source_derived`, `documented`, and `observed` describe the evidence behind a record. A source-derived example is synthetic; it is not a captured production response. Catalogue, schema, and package versions are separate. Source references identify reviewed revisions, not the release that first introduced a condition. Stable IDs survive wording changes; changed meaning requires review. [Read this page as Markdown](https://errorgram.rmbk.me/matching.md) --- # Contribute a condition Canonical page: https://errorgram.rmbk.me/contributing/ Start with a failure that changes how a bot should respond. Show the response, the API method, and the evidence behind your explanation. ## Make the change 1. Add or update a condition in [`catalogue/errors.json`](https://github.com/uburuntu/errorgram/blob/main/catalogue/errors.json). Keep its stable ID when wording changes but meaning does not. 2. Cite a pinned source revision, official documentation, or a reproducible observation. Distinguish an observed condition from a possible cause. 3. Add a case to [`fixtures/conformance.json`](https://github.com/uburuntu/errorgram/blob/main/fixtures/conformance.json). Include a nearby response that should not match when that distinction matters. 4. Run `make generate` and `make check`, then open a [pull request](https://github.com/uburuntu/errorgram/pulls). Edit the catalogue to change a condition's reference page. Edit the Markdown under `site/src/content/docs/` to improve an authored guide. Generated files carry the same data into the SDKs, website, and agent exports. ## Write what you can support Keep descriptions short and concrete. Prefer “The bot cannot resolve this chat” to a claim that the chat was deleted. One response can have several causes. Public examples must omit bot tokens, token-bearing URLs, and private message content. Label synthetic examples as synthetic. Reading source provides useful evidence, but it does not establish live hosted behavior. Adapters preserve framework fields, catch compatibility, and the original exception. A match must never trigger a retry or change application state. ## Keep the inventory open The catalogue, generated bindings, documentation, and original project code use the [MIT license](https://github.com/uburuntu/errorgram/blob/main/LICENSE). External source references retain their own licenses. Have a new response but no complete patch? [Try the playground](https://errorgram.rmbk.me/playground/), then [open the unknown-error form](https://github.com/uburuntu/errorgram/issues/new?template=unknown-error.yml) with a sanitized example, the method, framework version, and what you have verified. The form starts empty; the playground never copies your input into it. [Follow upstream changes](https://errorgram.rmbk.me/updating/) · [Read this page as Markdown](https://errorgram.rmbk.me/contributing.md) --- # Follow upstream changes Canonical page: https://errorgram.rmbk.me/updating/ Telegram adds methods, rewrites messages, and changes how errors reach the Bot API. Errorgram tracks those changes against a pinned source revision. The survey produces candidates for review. It does not change the catalogue or recommend a recovery action. ## Monthly review report The [upstream survey workflow](https://github.com/uburuntu/errorgram/actions/workflows/upstream.yml) runs on the first day of each month at 06:17 UTC and can also be started manually. Download its report artifact from the workflow run; artifacts are retained for 90 days. Review the report before proposing a catalogue change. The workflow never accepts candidates into the catalogue automatically. ## Scan a revision Use a local clone of the [official server](https://github.com/tdlib/telegram-bot-api). Fetching updates is separate from scanning: ```sh git -C ../telegram-bot-api fetch origin --tags python tools/upstream.py scan \ --source ../telegram-bot-api \ --ref e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1 \ --output .cache/upstream-next.json python tools/upstream.py diff \ catalogue/upstream.json .cache/upstream-next.json \ --output .cache/upstream-diff.json ``` Choose the tag or commit to review. `--ref` resolves to an immutable commit; omitting it uses `HEAD`. The scanner reads committed Git objects, so it neither switches branches nor includes staged, edited, or untracked files. Dirty tracked source is reported as context. TDLib does not need to be checked out. If your network requires bypassing proxy variables, prefix the fetch command with `env -u HTTP_PROXY -u HTTPS_PROXY -u http_proxy -u https_proxy`. ## Read the diff | Field | What changed | | --- | --- | | `added`, `removed` | Candidate messages and expressions. | | `normalizer_changes` | Message rewriting, including branches and codes. | | `occurrence_changes` | Moved or duplicated call sites; line shifts do not create new candidates. | | `file_changes` and method lists | Context for changes the lexer cannot interpret. | Each snapshot records the API version, commit, TDLib pin, and source hashes. Candidate fingerprints belong to the scanner; they are separate from Errorgram condition IDs. ## Review before accepting Trace each useful candidate to a response path. An internal status, a normalization input, and a public description can contain different text. Dynamic expressions need context; a source literal alone does not establish a reachable API response. For a catalogue update, retain the stable condition ID where its meaning holds, pin its evidence, and add representative matching and nonmatching fixtures. Keep the verification status honest: reading source is not a live reproduction. Regenerate bindings and documentation with `make generate`, then run `make check` before replacing the baseline. ## Understand the survey's limits The lexer skips comments, quoted code, declarations, and common logging statements. It joins adjacent literals and retains dynamic expressions. It does not compile C++, expand macros, resolve templates, or trace calls. TDLib, remote Telegram responses, and dependency behavior remain outside the survey. Counts describe source candidates, not complete Bot API coverage. [Contribute a condition](https://errorgram.rmbk.me/contributing/) · [Read this page as Markdown](https://errorgram.rmbk.me/updating.md) --- # For AI agents Canonical page: https://errorgram.rmbk.me/agents/ Use structured data for matching rules and plain Markdown for explanations. Both come from the same catalogue as the human reference and SDKs. ## Choose an entry point | Resource | Use it for | | --- | --- | | [llms.txt](https://errorgram.rmbk.me/llms.txt) | A short introduction and an index of the documentation. | | [llms-full.txt](https://errorgram.rmbk.me/llms-full.txt) | The complete guides and condition reference in one file. | | [catalogue.json](https://errorgram.rmbk.me/catalogue.json) | IDs, exact rules, examples, diagnostic limits, and evidence. | | [schema.json](https://errorgram.rmbk.me/schema.json) | The JSON Schema for catalogue validation. | | [Catalogue as Markdown](https://errorgram.rmbk.me/catalogue.md) | A compact list of supported conditions. | Every guide and condition has a plain Markdown version. For example: ```text https://errorgram.rmbk.me/python.md https://errorgram.rmbk.me/playground.md https://errorgram.rmbk.me/errors/chat.not_found.md ``` The website URL for that condition is `https://errorgram.rmbk.me/errors/chat.not_found/`. The ID is part of the permanent path. ## Use the evidence carefully 1. Read the catalogue version and coverage metadata before assuming a condition is supported. 2. Match against the response code, description, structured parameters, and method context. A shared phrase is not enough. 3. Keep possible causes separate from what the response establishes. Cite the condition page and its pinned evidence. 4. Preserve unknown or ambiguous results. Leave retries, suppression, and state changes to the application. Each record links to its source evidence and any live observations. Examples use synthetic data. Coverage is incomplete. Transport failures and framework validation errors are outside the inventory. `llms.txt` is a discovery convention, not a requirement for clients. All exports are ordinary static files available without JavaScript or authentication. [How matching works](https://errorgram.rmbk.me/matching/) · [Read this page as Markdown](https://errorgram.rmbk.me/agents.md) --- # Error catalogue **45 conditions** · catalogue `0.1.0` · reviewed 2026-09-16 Start with the response text, a stable ID, or a framework exception name. Each page explains the match, its limits, and the evidence behind it. Telegram Bot API error responses, reviewed against source with selected hosted observations. Live verification is incomplete; see each record’s evidence. Synthetic examples derived from the cited source. Coverage is incomplete. Unrecognized responses remain unknown. | Condition | Meaning | | --- | --- | | [auth.invalid\_token\_format](https://errorgram.rmbk.me/errors/auth.invalid_token_format/) | The server rejected the token during local validation. | | [bot.blocked\_by\_user](https://errorgram.rmbk.me/errors/bot.blocked_by_user/) | The user has blocked the bot. | | [bot.kicked](https://errorgram.rmbk.me/errors/bot.kicked/) | The bot was removed or banned from the chat. | | [bot.not\_member](https://errorgram.rmbk.me/errors/bot.not_member/) | The bot lacks the chat membership required for this operation. | | [chat.group\_deleted](https://errorgram.rmbk.me/errors/chat.group_deleted/) | Telegram reports that the group chat was deleted. | | [chat.migrated](https://errorgram.rmbk.me/errors/chat.migrated/) | The group has moved to a supergroup with a new ID. | | [chat.not\_found](https://errorgram.rmbk.me/errors/chat.not_found/) | The bot could not resolve this chat. | | [file.download\_too\_large](https://errorgram.rmbk.me/errors/file.download_too_large/) | The file exceeds the server’s non-local download limit. | | [file.id\_invalid](https://errorgram.rmbk.me/errors/file.id_invalid/) | The server could not resolve the supplied file\_id. | | [file.id\_missing](https://errorgram.rmbk.me/errors/file.id_missing/) | The file\_id argument is missing or empty. | | [file.unavailable](https://errorgram.rmbk.me/errors/file.unavailable/) | The file could not be downloaded with the supplied identifier. | | [file.url\_content\_type\_invalid](https://errorgram.rmbk.me/errors/file.url_content_type_invalid/) | The retrieved web content is unsuitable for the requested operation. | | [file.url\_fetch\_failed](https://errorgram.rmbk.me/errors/file.url_fetch_failed/) | Telegram could not retrieve content from the HTTP URL. | | [file.url\_invalid](https://errorgram.rmbk.me/errors/file.url_invalid/) | The HTTP URL was rejected. | | [file.url\_upload\_failed](https://errorgram.rmbk.me/errors/file.url_upload_failed/) | Telegram could not upload the file from its URL. | | [format.entity\_not\_object](https://errorgram.rmbk.me/errors/format.entity_not_object/) | An item in the message entities array is not a JSON object. | | [format.entity\_type\_unsupported](https://errorgram.rmbk.me/errors/format.entity_type_unsupported/) | A message entity specifies an unsupported type. | | [format.parse\_mode\_unsupported](https://errorgram.rmbk.me/errors/format.parse_mode_unsupported/) | The requested parse\_mode is unsupported. | | [markup.invalid\_json](https://errorgram.rmbk.me/errors/markup.invalid_json/) | The reply\_markup argument is not valid JSON. | | [markup.not\_object](https://errorgram.rmbk.me/errors/markup.not_object/) | The reply\_markup value is not a JSON object. | | [markup.too\_long](https://errorgram.rmbk.me/errors/markup.too_long/) | Telegram rejected the size of the reply markup. | | [member.is\_administrator](https://errorgram.rmbk.me/errors/member.is_administrator/) | The operation was rejected because the target user is a chat administrator. | | [message.copy\_not\_found](https://errorgram.rmbk.me/errors/message.copy_not_found/) | The message to copy could not be resolved. | | [message.delete\_forbidden](https://errorgram.rmbk.me/errors/message.delete_forbidden/) | Telegram rejected deletion of the message. | | [message.delete\_not\_found](https://errorgram.rmbk.me/errors/message.delete_not_found/) | The message to delete could not be resolved. | | [message.edit\_not\_found](https://errorgram.rmbk.me/errors/message.edit_not_found/) | The message to edit could not be resolved. | | [message.forward\_not\_found](https://errorgram.rmbk.me/errors/message.forward_not_found/) | The message to forward could not be resolved. | | [message.identifier\_missing](https://errorgram.rmbk.me/errors/message.identifier_missing/) | The request did not specify a message identifier for the selected operation. | | [message.identifiers\_missing](https://errorgram.rmbk.me/errors/message.identifiers_missing/) | The request did not specify the list of message identifiers. | | [message.not\_modified](https://errorgram.rmbk.me/errors/message.not_modified/) | The requested message content and reply markup are unchanged. | | [message.pin\_not\_found](https://errorgram.rmbk.me/errors/message.pin_not_found/) | The message to pin could not be resolved. | | [message.reply\_not\_found](https://errorgram.rmbk.me/errors/message.reply_not_found/) | The message being replied to could not be resolved. | | [permissions.invalid\_json](https://errorgram.rmbk.me/errors/permissions.invalid_json/) | The permissions argument is not valid JSON. | | [permissions.not\_object](https://errorgram.rmbk.me/errors/permissions.not_object/) | The permissions value is not a JSON object. | | [query.invalid\_or\_expired](https://errorgram.rmbk.me/errors/query.invalid_or_expired/) | The query ID is invalid or its response window has expired. | | [request.retry\_after](https://errorgram.rmbk.me/errors/request.retry_after/) | The server asks the bot to wait before trying again. | | [routing.token\_not\_served](https://errorgram.rmbk.me/errors/routing.token_not_served/) | The token failed the server’s bot-ID or routing check. | | [server.restarting](https://errorgram.rmbk.me/errors/server.restarting/) | The bot client is closing for a server restart. | | [session.logged\_out](https://errorgram.rmbk.me/errors/session.logged_out/) | The bot session has logged out. | | [text.empty](https://errorgram.rmbk.me/errors/text.empty/) | The message text is empty. | | [text.too\_long](https://errorgram.rmbk.me/errors/text.too_long/) | The text exceeds the limit checked by this response path. | | [updates.concurrent\_poll](https://errorgram.rmbk.me/errors/updates.concurrent_poll/) | Another getUpdates request interrupted the pending long poll. | | [updates.webhook\_active](https://errorgram.rmbk.me/errors/updates.webhook_active/) | Polling was requested while a webhook is active or being configured. | | [user.deactivated](https://errorgram.rmbk.me/errors/user.deactivated/) | Telegram rejected the operation because the user is deactivated. | | [webhook.certificate\_too\_large](https://errorgram.rmbk.me/errors/webhook.certificate_too_large/) | The uploaded webhook certificate exceeds the server’s size limit. | Download the [catalogue JSON](https://errorgram.rmbk.me/catalogue.json) or [JSON Schema](https://errorgram.rmbk.me/schema.json). For programmatic retrieval, see [AI agents](https://errorgram.rmbk.me/agents/). --- # Auth invalid token format · auth.invalid\_token\_format Canonical page: https://errorgram.rmbk.me/errors/auth.invalid_token_format/ **Stable ID:** `auth.invalid_token_format` · **Evidence:** source derived The server rejected the token during local validation. This signature is narrower than generic Unauthorized. Other malformed-token paths may produce different codes. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **401**. Exact description: ```text Unauthorized: invalid token specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getMe`. ## Possible causes - A locally checked token structure or numeric identifier constraint failed. ## Before deciding what to do **Application decision:** correct token configuration. **Repeat request:** after configuration change. - Verify the configured token without placing it in logs or inventory submissions. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getMe`. ```json { "ok": false, "error_code": 401, "description": "Unauthorized: invalid token specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 401, "description": "Unauthorized: invalid token specified", } result = classify(response, method='getMe') assert result.id == 'auth.invalid_token_format' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 401, "description": "Unauthorized: invalid token specified" }; const result = classify(response, { method: "getMe" }); if (result.status === "matched" && result.id === "auth.invalid_token_format") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.AuthInvalidTokenFormat` | | aiogram | `errorgram.aiogram.AuthInvalidTokenFormat` extends `TelegramUnauthorizedError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `auth.invalid_token_format` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/ClientManager.cpp:73–84](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/ClientManager.cpp#L73-L84). Two local checks return this exact response; the intervening check can return 421. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/auth.invalid_token_format.md) · [Condition JSON](https://errorgram.rmbk.me/errors/auth.invalid_token_format.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Bot blocked by user · bot.blocked\_by\_user Canonical page: https://errorgram.rmbk.me/errors/bot.blocked_by_user/ **Stable ID:** `bot.blocked_by_user` · **Evidence:** source derived The user has blocked the bot. The response establishes the current rejection, not that access can never be restored. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot was blocked by the user ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`. ## Possible causes - The recipient has blocked the bot. ## Before deciding what to do **Application decision:** suspend sends until access changes. **Repeat request:** after access change. - Use application policy to track reachability and resume only when there is evidence that access changed. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 403, "description": "Forbidden: bot was blocked by the user" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 403, "description": "Forbidden: bot was blocked by the user", } result = classify(response, method='sendMessage') assert result.id == 'bot.blocked_by_user' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 403, "description": "Forbidden: bot was blocked by the user" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "bot.blocked_by_user") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.BotBlockedByUser` | | aiogram | `errorgram.aiogram.BotBlockedByUser` extends `TelegramForbiddenError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `bot.blocked_by_user` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:127–129](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L127-L129). USER\_IS\_BLOCKED changes both the code (to 403) and the description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/bot.blocked_by_user.md) · [Condition JSON](https://errorgram.rmbk.me/errors/bot.blocked_by_user.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Bot kicked · bot.kicked Canonical page: https://errorgram.rmbk.me/errors/bot.kicked/ **Stable ID:** `bot.kicked` · **Evidence:** source derived The bot was removed or banned from the chat. The response does not identify who removed the bot or guarantee that rejoining is currently allowed. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. ### Rule 1 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot was kicked from the group chat ``` ### Rule 2 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot was kicked from the supergroup chat ``` ### Rule 3 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot was kicked from the channel chat ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `deleteMessage`. ## Possible causes - An active group records the bot as kicked. - The supergroup or channel membership status is banned. ## Before deciding what to do **Application decision:** restore bot membership. **Repeat request:** after access change. - An authorized chat administrator must restore the bot’s access before the application resumes the operation. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 403, "description": "Forbidden: bot was kicked from the group chat" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 403, "description": "Forbidden: bot was kicked from the group chat", } result = classify(response, method='sendMessage') assert result.id == 'bot.kicked' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 403, "description": "Forbidden: bot was kicked from the group chat" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "bot.kicked") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.BotKicked` | | aiogram | `errorgram.aiogram.BotKicked` extends `TelegramForbiddenError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `bot.kicked` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:8832–8833](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8832-L8833). An active group with a kicked bot fails edit or write access. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:8840–8847](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8840-L8847). Banned supergroup and channel memberships produce the corresponding descriptions. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/bot.kicked.md) · [Condition JSON](https://errorgram.rmbk.me/errors/bot.kicked.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Bot not member · bot.not\_member Canonical page: https://errorgram.rmbk.me/errors/bot.not_member/ **Stable ID:** `bot.not_member` · **Evidence:** source derived The bot lacks the chat membership required for this operation. Membership requirements depend on the chat type, public access, and operation. This is separate from the explicit kicked response. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. ### Rule 1 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot is not a member of the group chat ``` ### Rule 2 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot is not a member of the supergroup chat ``` ### Rule 3 - JSON `error_code`: **403**. Exact description: ```text Forbidden: bot is not a member of the channel chat ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `deleteMessage`. ## Possible causes - The bot has left an active group. - The bot is not a member of a supergroup or channel and the requested access requires membership. ## Before deciding what to do **Application decision:** restore bot membership. **Repeat request:** after access change. - Add or rejoin the bot with the required access through an authorized chat administrator before resuming. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 403, "description": "Forbidden: bot is not a member of the group chat" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 403, "description": "Forbidden: bot is not a member of the group chat", } result = classify(response, method='sendMessage') assert result.id == 'bot.not_member' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 403, "description": "Forbidden: bot is not a member of the group chat" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "bot.not_member") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.BotNotMember` | | aiogram | `errorgram.aiogram.BotNotMember` extends `TelegramForbiddenError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `bot.not_member` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:8835–8836](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8835-L8836). An active group with a departed bot fails edit or write access. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:8850–8856](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8850-L8856). Public visibility and requested access determine whether supergroup or channel membership is required. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9045–9055](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9045-L9055). Banned, left, and restricted nonmember statuses do not count as membership. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/bot.not_member.md) · [Condition JSON](https://errorgram.rmbk.me/errors/bot.not_member.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Chat group deleted · chat.group\_deleted Canonical page: https://errorgram.rmbk.me/errors/chat.group_deleted/ **Stable ID:** `chat.group_deleted` · **Evidence:** source derived Telegram reports that the group chat was deleted. This signature is distinct from group migration and does not supply a replacement chat identifier. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **403**. Exact description: ```text Forbidden: the group chat was deleted ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `getChatAdministrators`. ## Possible causes - The basic group is inactive and has no recorded supergroup replacement in this access check. ## Before deciding what to do **Application decision:** retire or review chat target. **Repeat request:** after relevant change. - Review the stored target and stop repeated sends; use a replacement only when it is independently established. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 403, "description": "Forbidden: the group chat was deleted" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 403, "description": "Forbidden: the group chat was deleted", } result = classify(response, method='sendMessage') assert result.id == 'chat.group_deleted' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 403, "description": "Forbidden: the group chat was deleted" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "chat.group_deleted") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.ChatGroupDeleted` | | aiogram | `errorgram.aiogram.ChatGroupDeleted` extends `TelegramForbiddenError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `chat.group_deleted` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:8814–8829](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8814-L8829). The inactive-group branch distinguishes a recorded migration from the deleted-group response. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/chat.group_deleted.md) · [Condition JSON](https://errorgram.rmbk.me/errors/chat.group_deleted.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Chat migrated · chat.migrated Canonical page: https://errorgram.rmbk.me/errors/chat.migrated/ **Stable ID:** `chat.migrated` · **Evidence:** observed The group has moved to a supergroup with a new ID. Use the structured replacement identifier; a description alone does not supply the new target. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. - `parameters.migrate_to_chat_id`: a nonzero safe integer. The structured parameter decides the match; the description may vary. See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`. ## Possible causes - The request addresses a group that was upgraded to a supergroup. ## Before deciding what to do **Application decision:** migrate chat reference. **Repeat request:** after target update. - Update the intended chat reference from parameters.migrate\_to\_chat\_id, account for concurrent updates, and bound retries. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts Values extracted into `result.facts`: - `migrate_to_chat_id`: a nonzero safe integer, from `parameters.migrate_to_chat_id`. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: group chat was upgraded to a supergroup chat", "parameters": { "migrate_to_chat_id": -1001234567890 } } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: group chat was upgraded to a supergroup chat", "parameters": { "migrate_to_chat_id": -1001234567890, }, } result = classify(response, method='sendMessage') assert result.id == 'chat.migrated' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: group chat was upgraded to a supergroup chat", "parameters": { "migrate_to_chat_id": -1001234567890 } }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "chat.migrated") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.ChatMigrated` | | aiogram | `errorgram.aiogram.ChatMigrated` extends `TelegramMigrateToChat` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `chat.migrated` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). getChatAdministrators on an already migrated basic group returned the migration parameter. Its value is synthetic in the report. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:8821–8827](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8821-L8827). The replacement chat ID is placed in response parameters. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Official documentation](https://core.telegram.org/bots/api#responseparameters). Documents migrate\_to\_chat\_id, including its maximum of 52 significant bits. Accessed 2026-09-15. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/chat.migrated.md) · [Condition JSON](https://errorgram.rmbk.me/errors/chat.migrated.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Chat not found · chat.not\_found Canonical page: https://errorgram.rmbk.me/errors/chat.not_found/ **Stable ID:** `chat.not_found` · **Evidence:** source derived The bot could not resolve this chat. This is not proof that the chat was deleted, the bot was blocked, or the identifier is permanently unusable. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: chat not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `getChat`. ## Possible causes - An upstream lookup error was replaced with the generic chat lookup message. - A username resolved to a chat type that this lookup does not allow. ## Before deciding what to do **Application decision:** inspect target and access. **Repeat request:** after relevant change. - Verify the identifier, target type and bot access before changing stored chat records. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getChat`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: chat not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: chat not found", } result = classify(response, method='getChat') assert result.id == 'chat.not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: chat not found" }; const result = classify(response, { method: "getChat" }); if (result.status === "matched" && result.id === "chat.not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.ChatNotFound` | | aiogram | `errorgram.aiogram.ChatNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `chat.not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:7239–7266](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7239-L7266). A fallback masks upstream 400-class errors, and a separate local branch emits the same description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). Some upstream codes are converted to 400 before the fallback description is applied. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/chat.not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/chat.not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File download too large · file.download\_too\_large Canonical page: https://errorgram.rmbk.me/errors/file.download_too_large/ **Stable ID:** `file.download_too_large` · **Evidence:** source derived The file exceeds the server’s non-local download limit. A bare file-is-too-big description without method context is insufficient for this download-specific classification. This is not an upload-size rule. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. - Required method: `getfile`, ignoring ASCII case. Exact description: ```text Bad Request: file is too big ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getFile`. Source guard applies when local\_mode is false. ## Possible causes - Expected or downloaded file size exceeds MAX\_DOWNLOAD\_FILE\_SIZE while local mode is disabled. ## Before deciding what to do **Application decision:** change download strategy. **Repeat request:** after relevant change. - Use a suitable smaller file or deliberately configure a server with the required local-mode download capability. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. Version-specific metadata is available in `result.entry` under `facts`. These values are catalogue metadata, not measurements from the response. ```json { "verified_limit_bytes": 20971520, "limit_version_source": "server-10.3" } ``` ## Example Synthetic examples derived from the cited source. API method: `getFile`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: file is too big" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: file is too big", } result = classify(response, method='getFile') assert result.id == 'file.download_too_large' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: file is too big" }; const result = classify(response, { method: "getFile" }); if (result.status === "matched" && result.id === "file.download_too_large") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileDownloadTooLarge` | | aiogram | `errorgram.aiogram.FileDownloadTooLarge` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.download_too_large` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:17032–17049](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17032-L17049). getFile reaches the size check guarded by local\_mode. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9373–9383](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9373-L9383). The download update path enforces the same limit. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.h:72](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.h#L72). The constant is 20 << 20 bytes in this revision. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.download_too_large.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.download_too_large.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File id invalid · file.id\_invalid Canonical page: https://errorgram.rmbk.me/errors/file.id_invalid/ **Stable ID:** `file.id_invalid` · **Evidence:** source derived The server could not resolve the supplied file\_id. The generic fallback does not identify a malformed ID, a bot-specific access issue, or permanent unavailability. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: invalid file_id ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getFile`. ## Possible causes - A remote-file lookup failed and the normalizer replaced its original error. ## Before deciding what to do **Application decision:** verify file identifier. **Repeat request:** after relevant change. - Check that this bot received the exact file\_id and that file\_unique\_id was not substituted. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getFile`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: invalid file_id" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: invalid file_id", } result = classify(response, method='getFile') assert result.id == 'file.id_invalid' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: invalid file_id" }; const result = classify(response, { method: "getFile" }); if (result.status === "matched" && result.id === "file.id_invalid") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileIdInvalid` | | aiogram | `errorgram.aiogram.FileIdInvalid` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.id_invalid` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:7525–7527](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7525-L7527). Remote-file lookup errors receive the invalid file\_id fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:17032–17035](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17032-L17035). getFile uses this remote-file lookup. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.id_invalid.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.id_invalid.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File id missing · file.id\_missing Canonical page: https://errorgram.rmbk.me/errors/file.id_missing/ **Stable ID:** `file.id_missing` · **Evidence:** observed The file\_id argument is missing or empty. This response concerns a missing file identifier; it does not validate an upload or a nonempty identifier. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: file_id not specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getFile`. ## Possible causes - The remote-file lookup received an empty file\_id. ## Before deciding what to do **Application decision:** supply file identifier. **Repeat request:** after relevant change. - Use the file\_id supplied for this bot by Telegram, rather than file\_unique\_id. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getFile`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: file_id not specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: file_id not specified", } result = classify(response, method='getFile') assert result.id == 'file.id_missing' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: file_id not specified" }; const result = classify(response, { method: "getFile" }); if (result.status === "matched" && result.id === "file.id_missing") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileIdMissing` | | aiogram | `errorgram.aiogram.FileIdMissing` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.id_missing` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). getFile with an empty file\_id returned this description. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9034–9041](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9034-L9041). The remote-file helper directly rejects an empty file\_id. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:17032–17035](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17032-L17035). getFile passes its file\_id argument to the helper. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.id_missing.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.id_missing.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File unavailable · file.unavailable Canonical page: https://errorgram.rmbk.me/errors/file.unavailable/ **Stable ID:** `file.unavailable` · **Evidence:** source derived The file could not be downloaded with the supplied identifier. The source notes that this path also hides upstream 5xx and 429 errors. The response supplies no retry delay and does not prove that the ID is wrong. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: wrong file_id or the file is temporarily unavailable ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getFile`. ## Possible causes - A started download stopped before completion without an active shutdown or logout state. ## Before deciding what to do **Application decision:** check file and retry policy. **Repeat request:** after relevant change. - Verify the file\_id; if a temporary failure is plausible, apply a bounded retry policy without inventing a server delay. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getFile`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: wrong file_id or the file is temporarily unavailable" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: wrong file_id or the file is temporarily unavailable", } result = classify(response, method='getFile') assert result.id == 'file.unavailable' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: wrong file_id or the file is temporarily unavailable" }; const result = classify(response, { method: "getFile" }); if (result.status === "matched" && result.id === "file.unavailable") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileUnavailable` | | aiogram | `errorgram.aiogram.FileUnavailable` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.unavailable` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:9385–9396](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9385-L9396). An inactive, incomplete started download is converted to this generic 400 response. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:17056–17067](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17056-L17067). The download failure is forwarded to waiting getFile queries through the normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.unavailable.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.unavailable.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File url content type invalid · file.url\_content\_type\_invalid Canonical page: https://errorgram.rmbk.me/errors/file.url_content_type_invalid/ **Stable ID:** `file.url_content_type_invalid` · **Evidence:** source derived The retrieved web content is unsuitable for the requested operation. The mapping does not identify a required MIME type or prove which part of the retrieved content is unsuitable. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: wrong type of the web page content ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendPhoto`, `sendDocument`. ## Possible causes - The retrieved page did not provide usable media for the operation. ## Before deciding what to do **Application decision:** check url content. **Repeat request:** after relevant change. - Check that the URL serves the intended media and that the selected method accepts that media type. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendPhoto`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: wrong type of the web page content" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: wrong type of the web page content", } result = classify(response, method='sendPhoto') assert result.id == 'file.url_content_type_invalid' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: wrong type of the web page content" }; const result = classify(response, { method: "sendPhoto" }); if (result.status === "matched" && result.id === "file.url_content_type_invalid") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileUrlContentTypeInvalid` | | aiogram | `errorgram.aiogram.FileUrlContentTypeInvalid` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.url_content_type_invalid` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:118–119](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L118-L119). WEBPAGE\_MEDIA\_EMPTY is rewritten to this description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). The rewrite runs only after the error is normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.url_content_type_invalid.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.url_content_type_invalid.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File url fetch failed · file.url\_fetch\_failed Canonical page: https://errorgram.rmbk.me/errors/file.url_fetch_failed/ **Stable ID:** `file.url_fetch_failed` · **Evidence:** source derived Telegram could not retrieve content from the HTTP URL. The response does not distinguish DNS, network, TLS, HTTP, or origin-access failures. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: failed to get HTTP URL content ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendPhoto`, `sendDocument`. ## Possible causes - Retrieving content from the URL failed. ## Before deciding what to do **Application decision:** inspect url retrieval. **Repeat request:** after relevant change. - Check that Telegram can retrieve the resource without browser sessions or private-network access; retry only under a bounded policy. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendPhoto`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: failed to get HTTP URL content" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: failed to get HTTP URL content", } result = classify(response, method='sendPhoto') assert result.id == 'file.url_fetch_failed' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: failed to get HTTP URL content" }; const result = classify(response, { method: "sendPhoto" }); if (result.status === "matched" && result.id === "file.url_fetch_failed") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileUrlFetchFailed` | | aiogram | `errorgram.aiogram.FileUrlFetchFailed` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.url_fetch_failed` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:116–117](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L116-L117). WEBPAGE\_CURL\_FAILED is rewritten to this description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). The rewrite runs only after the error is normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.url_fetch_failed.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.url_fetch_failed.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File url invalid · file.url\_invalid Canonical page: https://errorgram.rmbk.me/errors/file.url_invalid/ **Stable ID:** `file.url_invalid` · **Evidence:** source derived The HTTP URL was rejected. The response does not identify the invalid URL component or establish whether the resource is reachable. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: wrong HTTP URL specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendPhoto`, `sendDocument`. ## Possible causes - The supplied external URL failed Telegram’s URL validation. ## Before deciding what to do **Application decision:** correct file url. **Repeat request:** after relevant change. - Provide a valid HTTP URL for the intended resource and check the selected method’s URL-input rules. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendPhoto`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: wrong HTTP URL specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: wrong HTTP URL specified", } result = classify(response, method='sendPhoto') assert result.id == 'file.url_invalid' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: wrong HTTP URL specified" }; const result = classify(response, { method: "sendPhoto" }); if (result.status === "matched" && result.id === "file.url_invalid") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileUrlInvalid` | | aiogram | `errorgram.aiogram.FileUrlInvalid` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.url_invalid` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:114–115](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L114-L115). Two upstream URL validation errors are rewritten to the same description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). The rewrite runs only after the error is normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.url_invalid.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.url_invalid.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # File url upload failed · file.url\_upload\_failed Canonical page: https://errorgram.rmbk.me/errors/file.url_upload_failed/ **Stable ID:** `file.url_upload_failed` · **Evidence:** source derived Telegram could not upload the file from its URL. The response mapping does not identify the original retrieval or file-generation failure. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: can't upload file by URL ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendPhoto`, `sendDocument`. ## Possible causes - Generating a file from the supplied URL failed. ## Before deciding what to do **Application decision:** inspect url file input. **Repeat request:** after relevant change. - Check the URL and file requirements; use a direct upload if the method supports it and the application can supply the file. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendPhoto`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: can't upload file by URL" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: can't upload file by URL", } result = classify(response, method='sendPhoto') assert result.id == 'file.url_upload_failed' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: can't upload file by URL" }; const result = classify(response, { method: "sendPhoto" }); if (result.status === "matched" && result.id === "file.url_upload_failed") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FileUrlUploadFailed` | | aiogram | `errorgram.aiogram.FileUrlUploadFailed` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `file.url_upload_failed` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:133–135](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L133-L135). File generation failed is rewritten to this description and code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). The rewrite runs only after the error is normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/file.url_upload_failed.md) · [Condition JSON](https://errorgram.rmbk.me/errors/file.url_upload_failed.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Format entity not object · format.entity\_not\_object Canonical page: https://errorgram.rmbk.me/errors/format.entity_not_object/ **Stable ID:** `format.entity_not_object` · **Evidence:** source derived An item in the message entities array is not a JSON object. This identifies an item-shape failure, not invalid offsets, lengths, or markup syntax. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: can't parse MessageEntity: expected an Object ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`, `sendPhoto`. ## Possible causes - An entities or caption\_entities array contains a non-object item. ## Before deciding what to do **Application decision:** correct entity objects. **Repeat request:** after relevant change. - Provide each entity as an object with the fields required by its type, using the API’s UTF-16 offset convention. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: expected an Object" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: expected an Object", } result = classify(response, method='sendMessage') assert result.id == 'format.entity_not_object' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: expected an Object" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "format.entity_not_object") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FormatEntityNotObject` | | aiogram | `errorgram.aiogram.FormatEntityNotObject` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `format.entity_not_object` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:11938–11946](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11938-L11946). Entity parsing rejects a non-object item before reading its fields. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:11984–11989](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11984-L11989). The formatting helper wraps the item error in the MessageEntity description with code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/format.entity_not_object.md) · [Condition JSON](https://errorgram.rmbk.me/errors/format.entity_not_object.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Format entity type unsupported · format.entity\_type\_unsupported Canonical page: https://errorgram.rmbk.me/errors/format.entity_type_unsupported/ **Stable ID:** `format.entity_type_unsupported` · **Evidence:** source derived A message entity specifies an unsupported type. The response does not identify the offending array item or establish whether its other fields are valid. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: can't parse MessageEntity: Unsupported type specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`, `sendPhoto`. ## Possible causes - An entity object uses a type that the server’s entity parser does not support. ## Before deciding what to do **Application decision:** correct entity type. **Repeat request:** after relevant change. - Use a supported MessageEntity type and include its required fields. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: Unsupported type specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: Unsupported type specified", } result = classify(response, method='sendMessage') assert result.id == 'format.entity_type_unsupported' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: can't parse MessageEntity: Unsupported type specified" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "format.entity_type_unsupported") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FormatEntityTypeUnsupported` | | aiogram | `errorgram.aiogram.FormatEntityTypeUnsupported` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `format.entity_type_unsupported` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:11929–11946](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11929-L11946). Unrecognized entity types return this literal, which propagates through get\_text\_entity. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:11984–11989](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11984-L11989). The formatting helper wraps the item error with an explicit 400 code and preserves its initial capital. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/format.entity_type_unsupported.md) · [Condition JSON](https://errorgram.rmbk.me/errors/format.entity_type_unsupported.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Format parse mode unsupported · format.parse\_mode\_unsupported Canonical page: https://errorgram.rmbk.me/errors/format.parse_mode_unsupported/ **Stable ID:** `format.parse_mode_unsupported` · **Evidence:** observed The requested parse\_mode is unsupported. The server lowercases parse\_mode before checking it. This response does not identify a malformed entity inside a supported mode. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: unsupported parse_mode ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`, `sendPhoto`. ## Possible causes - Nonempty text was supplied with a parse\_mode that the server does not recognize. ## Before deciding what to do **Application decision:** correct parse mode. **Repeat request:** after relevant change. - Choose a supported parse\_mode, or omit it and use plain text or explicit entities. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: unsupported parse_mode" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: unsupported parse_mode", } result = classify(response, method='sendMessage') assert result.id == 'format.parse_mode_unsupported' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: unsupported parse_mode" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "format.parse_mode_unsupported") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.FormatParseModeUnsupported` | | aiogram | `errorgram.aiogram.FormatParseModeUnsupported` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `format.parse_mode_unsupported` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). sendMessage with an unsupported parse\_mode returned this description. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:11961–11977](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11961-L11977). Nonempty text accepts markdown, markdownv2, html, or the no-parsing path; other modes fail. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/format.parse_mode_unsupported.md) · [Condition JSON](https://errorgram.rmbk.me/errors/format.parse_mode_unsupported.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Markup invalid json · markup.invalid\_json Canonical page: https://errorgram.rmbk.me/errors/markup.invalid_json/ **Stable ID:** `markup.invalid_json` · **Evidence:** source derived The reply\_markup argument is not valid JSON. Valid JSON with the wrong shape or invalid button fields produces different errors. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: can't parse reply keyboard markup JSON object ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageReplyMarkup`. ## Possible causes - A nonempty reply\_markup argument failed JSON decoding. ## Before deciding what to do **Application decision:** correct reply markup json. **Repeat request:** after relevant change. - Serialize reply\_markup as a JSON object with the structure required by the selected keyboard type. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: can't parse reply keyboard markup JSON object" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: can't parse reply keyboard markup JSON object", } result = classify(response, method='sendMessage') assert result.id == 'markup.invalid_json' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: can't parse reply keyboard markup JSON object" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "markup.invalid_json") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MarkupInvalidJson` | | aiogram | `errorgram.aiogram.MarkupInvalidJson` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `markup.invalid_json` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:10504–10518](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L10504-L10518). The reply\_markup parser emits this literal only when JSON decoding fails. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/markup.invalid_json.md) · [Condition JSON](https://errorgram.rmbk.me/errors/markup.invalid_json.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Markup not object · markup.not\_object Canonical page: https://errorgram.rmbk.me/errors/markup.not_object/ **Stable ID:** `markup.not_object` · **Evidence:** source derived The reply\_markup value is not a JSON object. This response does not validate the contents of an otherwise well-formed keyboard object. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: object expected as reply markup ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageReplyMarkup`. ## Possible causes - reply\_markup decoded successfully but its top-level value is not an object. ## Before deciding what to do **Application decision:** correct reply markup shape. **Repeat request:** after relevant change. - Use a reply\_markup object instead of a top-level array, scalar, or null value. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: object expected as reply markup" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: object expected as reply markup", } result = classify(response, method='sendMessage') assert result.id == 'markup.not_object' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: object expected as reply markup" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "markup.not_object") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MarkupNotObject` | | aiogram | `errorgram.aiogram.MarkupNotObject` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `markup.not_object` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:10521–10525](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L10521-L10525). The decoded reply markup must have object type. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/markup.not_object.md) · [Condition JSON](https://errorgram.rmbk.me/errors/markup.not_object.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Markup too long · markup.too\_long Canonical page: https://errorgram.rmbk.me/errors/markup.too_long/ **Stable ID:** `markup.too_long` · **Evidence:** source derived Telegram rejected the size of the reply markup. The mapping does not specify a size limit or identify which keyboard field exceeds it. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: reply markup is too long ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageReplyMarkup`. ## Possible causes - The reply markup exceeds a size constraint enforced by Telegram. ## Before deciding what to do **Application decision:** reduce reply markup. **Repeat request:** after relevant change. - Reduce the keyboard or button payload and check the current limits for the chosen button types. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: reply markup is too long" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: reply markup is too long", } result = classify(response, method='sendMessage') assert result.id == 'markup.too_long' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: reply markup is too long" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "markup.too_long") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MarkupTooLong` | | aiogram | `errorgram.aiogram.MarkupTooLong` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `markup.too_long` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:121–123](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L121-L123). REPLY\_MARKUP\_TOO\_LONG becomes this description in the code-400 branch. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). Normalizes lower codes, 404, and uppercase machine-style 403 errors to 400 before rewriting. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/markup.too_long.md) · [Condition JSON](https://errorgram.rmbk.me/errors/markup.too_long.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Member is administrator · member.is\_administrator Canonical page: https://errorgram.rmbk.me/errors/member.is_administrator/ **Stable ID:** `member.is_administrator` · **Evidence:** source derived The operation was rejected because the target user is a chat administrator. The mapping does not identify the user’s exact administrative role or authorize changing it. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: user is an administrator of the chat ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `banChatMember`, `restrictChatMember`. ## Possible causes - The requested action targets a chat administrator. ## Before deciding what to do **Application decision:** review target member role. **Repeat request:** after relevant change. - Confirm the intended user and current role; any necessary role change must follow the chat’s authorization policy. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `banChatMember`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: user is an administrator of the chat" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: user is an administrator of the chat", } result = classify(response, method='banChatMember') assert result.id == 'member.is_administrator' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: user is an administrator of the chat" }; const result = classify(response, { method: "banChatMember" }); if (result.status === "matched" && result.id === "member.is_administrator") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MemberIsAdministrator` | | aiogram | `errorgram.aiogram.MemberIsAdministrator` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `member.is_administrator` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:130–132](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L130-L132). USER\_ADMIN\_INVALID becomes this description with code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–106](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L106). Uppercase machine-style 403 errors can become 400 before this rewrite. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/member.is_administrator.md) · [Condition JSON](https://errorgram.rmbk.me/errors/member.is_administrator.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message copy not found · message.copy\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.copy_not_found/ **Stable ID:** `message.copy_not_found` · **Evidence:** source derived The message to copy could not be resolved. The response does not distinguish a deleted message from an incorrect identifier, missing access or a masked lookup error. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to copy not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `copyMessage`. ## Possible causes - The message identifier is missing or nonpositive. - The bot cannot access messages in the chat. - A message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect message target and access. **Repeat request:** after relevant change. - Check the chat and message identifiers together, then confirm the bot can access the target message. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `copyMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to copy not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to copy not found", } result = classify(response, method='copyMessage') assert result.id == 'message.copy_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to copy not found" }; const result = classify(response, { method: "copyMessage" }); if (result.status === "matched" && result.id === "message.copy_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageCopyNotFound` | | aiogram | `errorgram.aiogram.MessageCopyNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.copy_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:14373–14385](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L14373-L14385). The copyMessage path checks the source as "message to copy". Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9084–9102](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9084-L9102). Missing identifiers and unavailable message access produce this operation-specific fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). Failed lookups use the same fallback when an empty result is not allowed. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.copy_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.copy_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message delete forbidden · message.delete\_forbidden Canonical page: https://errorgram.rmbk.me/errors/message.delete_forbidden/ **Stable ID:** `message.delete_forbidden` · **Evidence:** source derived Telegram rejected deletion of the message. The source proves the response mapping, not which deletion restriction caused a particular failure. The causes above are diagnostic hypotheses. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message can't be deleted ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `deleteMessage`, `deleteMessages`. ## Possible causes - A permissions, message-type or message-age restriction may prevent deletion. ## Before deciding what to do **Application decision:** check deletion eligibility. **Repeat request:** after relevant change. - Check the current deleteMessage rules and bot permissions; a permanent message restriction may have no repair. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `deleteMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message can't be deleted" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message can't be deleted", } result = classify(response, method='deleteMessage') assert result.id == 'message.delete_forbidden' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message can't be deleted" }; const result = classify(response, { method: "deleteMessage" }); if (result.status === "matched" && result.id === "message.delete_forbidden") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageDeleteForbidden` | | aiogram | `errorgram.aiogram.MessageDeleteForbidden` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.delete_forbidden` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:151–153](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L151-L153). MESSAGE\_DELETE\_FORBIDDEN is rewritten before the Bad Request prefix is added. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.delete_forbidden.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.delete_forbidden.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message delete not found · message.delete\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.delete_not_found/ **Stable ID:** `message.delete_not_found` · **Evidence:** observed The message to delete could not be resolved. The response does not distinguish a deleted message from an incorrect identifier, missing access or a masked lookup error. Batch deletion can skip missing messages; this response is not an inventory of deleted items. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to delete not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `deleteMessage`, `deleteMessages`. ## Possible causes - The message identifier is missing or nonpositive. - The bot cannot access messages in the chat. - A message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect message target and access. **Repeat request:** after relevant change. - Check the chat and message identifiers together, then confirm the bot can access the target message. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `deleteMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to delete not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to delete not found", } result = classify(response, method='deleteMessage') assert result.id == 'message.delete_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to delete not found" }; const result = classify(response, { method: "deleteMessage" }); if (result.status === "matched" && result.id === "message.delete_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageDeleteNotFound` | | aiogram | `errorgram.aiogram.MessageDeleteNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.delete_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). Deleting the test bot’s own message again after confirmed deletion returned this description. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:14989–15006](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L14989-L15006). Single and batch deletion use "message to delete"; the batch path permits missing items. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9084–9102](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9084-L9102). Missing identifiers and unavailable message access produce this operation-specific fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). Failed lookups use the same fallback when an empty result is not allowed. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.delete_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.delete_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message edit not found · message.edit\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.edit_not_found/ **Stable ID:** `message.edit_not_found` · **Evidence:** observed The message to edit could not be resolved. The response does not distinguish a deleted message from an incorrect identifier, missing access or a masked lookup error. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to edit not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `editMessageText`, `editMessageCaption`, `editMessageReplyMarkup`. ## Possible causes - The message identifier is missing or nonpositive. - The bot cannot access messages in the chat. - A message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect message target and access. **Repeat request:** after relevant change. - Check the chat and message identifiers together, then confirm the bot can access the target message. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `editMessageText`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to edit not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to edit not found", } result = classify(response, method='editMessageText') assert result.id == 'message.edit_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to edit not found" }; const result = classify(response, { method: "editMessageText" }); if (result.status === "matched" && result.id === "message.edit_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageEditNotFound` | | aiogram | `errorgram.aiogram.MessageEditNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.edit_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). Editing the test bot’s own message after confirmed deletion returned this description. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:14694–14700](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L14694-L14700). The editMessageText path checks the target as "message to edit". Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9084–9102](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9084-L9102). Missing identifiers and unavailable message access produce this operation-specific fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). Failed lookups use the same fallback when an empty result is not allowed. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.edit_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.edit_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message forward not found · message.forward\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.forward_not_found/ **Stable ID:** `message.forward_not_found` · **Evidence:** source derived The message to forward could not be resolved. The response does not distinguish a deleted message from an incorrect identifier, missing access or a masked lookup error. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to forward not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `forwardMessage`, `forwardMessages`. ## Possible causes - The message identifier is missing or nonpositive. - The bot cannot access messages in the chat. - A message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect message target and access. **Repeat request:** after relevant change. - Check the chat and message identifiers together, then confirm the bot can access the target message. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `forwardMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to forward not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to forward not found", } result = classify(response, method='forwardMessage') assert result.id == 'message.forward_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to forward not found" }; const result = classify(response, { method: "forwardMessage" }); if (result.status === "matched" && result.id === "message.forward_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageForwardNotFound` | | aiogram | `errorgram.aiogram.MessageForwardNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.forward_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:14441–14452](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L14441-L14452). The forwardMessage path checks the source as "message to forward". Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9084–9102](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9084-L9102). Missing identifiers and unavailable message access produce this operation-specific fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). Failed lookups use the same fallback when an empty result is not allowed. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.forward_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.forward_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message identifier missing · message.identifier\_missing Canonical page: https://errorgram.rmbk.me/errors/message.identifier_missing/ **Stable ID:** `message.identifier_missing` · **Evidence:** source derived The request did not specify a message identifier for the selected operation. This signature does not diagnose all missing message\_id arguments; a chat-based lookup may return an operation-specific not-found error. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message identifier is not specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `editMessageText`, `editMessageCaption`. ## Possible causes - The inline-message path was selected without a nonempty inline\_message\_id. ## Before deciding what to do **Application decision:** supply message target. **Repeat request:** after relevant change. - Supply the intended inline\_message\_id or the appropriate chat\_id and message\_id pair. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `editMessageText`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message identifier is not specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message identifier is not specified", } result = classify(response, method='editMessageText') assert result.id == 'message.identifier_missing' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message identifier is not specified" }; const result = classify(response, { method: "editMessageText" }); if (result.status === "matched" && result.id === "message.identifier_missing") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageIdentifierMissing` | | aiogram | `errorgram.aiogram.MessageIdentifierMissing` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.identifier_missing` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:13540–13545](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13540-L13545). The inline-message identifier helper rejects an empty argument. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:14659–14665](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L14659-L14665). Editing takes this path when chat\_id is empty and the parsed message\_id is zero. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.identifier_missing.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.identifier_missing.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message identifiers missing · message.identifiers\_missing Canonical page: https://errorgram.rmbk.me/errors/message.identifiers_missing/ **Stable ID:** `message.identifiers_missing` · **Evidence:** source derived The request did not specify the list of message identifiers. An empty argument and an encoded empty JSON array are different inputs; this response covers the former. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message identifiers are not specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `deleteMessages`, `forwardMessages`, `copyMessages`. ## Possible causes - The message\_ids argument is absent or empty. ## Before deciding what to do **Application decision:** supply message identifiers. **Repeat request:** after relevant change. - Provide a JSON array of the intended message identifiers and check the method-specific count limit. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `deleteMessages`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message identifiers are not specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message identifiers are not specified", } result = classify(response, method='deleteMessages') assert result.id == 'message.identifiers_missing' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message identifiers are not specified" }; const result = classify(response, { method: "deleteMessages" }); if (result.status === "matched" && result.id === "message.identifiers_missing") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageIdentifiersMissing` | | aiogram | `errorgram.aiogram.MessageIdentifiersMissing` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.identifiers_missing` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:13500–13504](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13500-L13504). The list parser rejects an absent or empty argument before JSON decoding. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:15000–15003](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L15000-L15003). deleteMessages passes message\_ids to this parser. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.identifiers_missing.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.identifiers_missing.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message not modified · message.not\_modified Canonical page: https://errorgram.rmbk.me/errors/message.not_modified/ **Stable ID:** `message.not_modified` · **Evidence:** observed The requested message content and reply markup are unchanged. The response does not include the current message or establish the history of concurrent edits. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `editMessageText`, `editMessageCaption`, `editMessageReplyMarkup`. ## Possible causes - The requested edit repeats the current content and markup. ## Before deciding what to do **Application decision:** accept existing state if intended. **Repeat request:** unhelpful without change. - The application considers an already-applied desired state a successful outcome. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `editMessageText`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message", } result = classify(response, method='editMessageText') assert result.id == 'message.not_modified' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message is not modified: specified new message content and reply markup are exactly the same as a current content and reply markup of the message" }; const result = classify(response, { method: "editMessageText" }); if (result.status === "matched" && result.id === "message.not_modified") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageNotModified` | | aiogram | `errorgram.aiogram.MessageNotModified` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.not_modified` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). Editing a newly created bot message with identical text returned this description. The test message was then deleted. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:106–113](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L106-L113). MESSAGE\_NOT\_MODIFIED is rewritten here; prefix and initial-case handling are at lines 165-205. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.not_modified.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.not_modified.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message pin not found · message.pin\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.pin_not_found/ **Stable ID:** `message.pin_not_found` · **Evidence:** source derived The message to pin could not be resolved. The response does not distinguish a deleted message from an incorrect identifier, missing access or a masked lookup error. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to pin not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `pinChatMessage`. ## Possible causes - The message identifier is missing or nonpositive. - The bot cannot access messages in the chat. - A message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect message target and access. **Repeat request:** after relevant change. - Check the chat and message identifiers together, then confirm the bot can access the target message. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `pinChatMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to pin not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to pin not found", } result = classify(response, method='pinChatMessage') assert result.id == 'message.pin_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to pin not found" }; const result = classify(response, { method: "pinChatMessage" }); if (result.status === "matched" && result.id === "message.pin_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessagePinNotFound` | | aiogram | `errorgram.aiogram.MessagePinNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.pin_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:16054–16065](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L16054-L16065). The pinChatMessage path checks the target as "message to pin". Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:9084–9102](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9084-L9102). Missing identifiers and unavailable message access produce this operation-specific fallback. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). Failed lookups use the same fallback when an empty result is not allowed. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.pin_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.pin_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Message reply not found · message.reply\_not\_found Canonical page: https://errorgram.rmbk.me/errors/message.reply_not_found/ **Stable ID:** `message.reply_not_found` · **Evidence:** source derived The message being replied to could not be resolved. The response does not prove that the message was deleted. Reply settings and the referenced chat also affect this lookup. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message to be replied not found ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `sendPhoto`. ## Possible causes - The bot cannot access the referenced message. - A reply-message lookup failed and its original error was replaced. ## Before deciding what to do **Application decision:** inspect reply target and access. **Repeat request:** after relevant change. - Verify the reply message and chat; omit the reply only if the application permits sending without it. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message to be replied not found" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message to be replied not found", } result = classify(response, method='sendMessage') assert result.id == 'message.reply_not_found' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message to be replied not found" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "message.reply_not_found") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.MessageReplyNotFound` | | aiogram | `errorgram.aiogram.MessageReplyNotFound` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `message.reply_not_found` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:9190–9198](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L9190-L9198). Reply lookup uses this fallback for unavailable access or a failed required-message lookup. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:7390–7399](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L7390-L7399). allow\_sending\_without\_reply can permit an empty result instead of failing. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:85–108](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L85-L108). The fallback replaces only errors normalized to code 400. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/message.reply_not_found.md) · [Condition JSON](https://errorgram.rmbk.me/errors/message.reply_not_found.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Permissions invalid json · permissions.invalid\_json Canonical page: https://errorgram.rmbk.me/errors/permissions.invalid_json/ **Stable ID:** `permissions.invalid_json` · **Evidence:** source derived The permissions argument is not valid JSON. This is a request-format error; it does not establish whether the bot has permission to change chat rights. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: can't parse permissions JSON object ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `setChatPermissions`, `restrictChatMember`. ## Possible causes - The supplied permissions argument failed JSON decoding. ## Before deciding what to do **Application decision:** correct permissions json. **Repeat request:** after relevant change. - Serialize permissions as a ChatPermissions object and verify the intended boolean values. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `setChatPermissions`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: can't parse permissions JSON object" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: can't parse permissions JSON object", } result = classify(response, method='setChatPermissions') assert result.id == 'permissions.invalid_json' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: can't parse permissions JSON object" }; const result = classify(response, { method: "setChatPermissions" }); if (result.status === "matched" && result.id === "permissions.invalid_json") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.PermissionsInvalidJson` | | aiogram | `errorgram.aiogram.PermissionsInvalidJson` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `permissions.invalid_json` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:12555–12561](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L12555-L12561). An explicitly supplied permissions argument is decoded as JSON and rejected here if decoding fails. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/permissions.invalid_json.md) · [Condition JSON](https://errorgram.rmbk.me/errors/permissions.invalid_json.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Permissions not object · permissions.not\_object Canonical page: https://errorgram.rmbk.me/errors/permissions.not_object/ **Stable ID:** `permissions.not_object` · **Evidence:** source derived The permissions value is not a JSON object. This validates only the top-level shape, not individual rights or the bot’s authority to change them. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: object expected as permissions ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `setChatPermissions`, `restrictChatMember`. ## Possible causes - The permissions argument decoded to an array, scalar, or null instead of an object. ## Before deciding what to do **Application decision:** correct permissions shape. **Repeat request:** after relevant change. - Provide a ChatPermissions object with the intended rights, then check the operation’s access requirements. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `setChatPermissions`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: object expected as permissions" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: object expected as permissions", } result = classify(response, method='setChatPermissions') assert result.id == 'permissions.not_object' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: object expected as permissions" }; const result = classify(response, { method: "setChatPermissions" }); if (result.status === "matched" && result.id === "permissions.not_object") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.PermissionsNotObject` | | aiogram | `errorgram.aiogram.PermissionsNotObject` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `permissions.not_object` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:12564–12566](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L12564-L12566). Decoded permissions must have object type. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/permissions.not_object.md) · [Condition JSON](https://errorgram.rmbk.me/errors/permissions.not_object.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Query invalid or expired · query.invalid\_or\_expired Canonical page: https://errorgram.rmbk.me/errors/query.invalid_or_expired/ **Stable ID:** `query.invalid_or_expired` · **Evidence:** source derived The query ID is invalid or its response window has expired. The description explicitly combines causes; it does not establish a universal timeout duration. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: query is too old and response timeout expired or query ID is invalid ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `answerCallbackQuery`. ## Possible causes - The query identifier is invalid. - The response arrived after the query's response window. ## Before deciding what to do **Application decision:** verify identifier and response timing. **Repeat request:** unhelpful for expired identifier. - Use the identifier from the correct incoming query and respond promptly to future queries. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `answerCallbackQuery`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: query is too old and response timeout expired or query ID is invalid" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: query is too old and response timeout expired or query ID is invalid", } result = classify(response, method='answerCallbackQuery') assert result.id == 'query.invalid_or_expired' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: query is too old and response timeout expired or query ID is invalid" }; const result = classify(response, { method: "answerCallbackQuery" }); if (result.status === "matched" && result.id === "query.invalid_or_expired") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.QueryInvalidOrExpired` | | aiogram | `errorgram.aiogram.QueryInvalidOrExpired` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `query.invalid_or_expired` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:148–150](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L148-L150). QUERY\_ID\_INVALID is deliberately expanded to a description containing alternatives. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/query.invalid_or_expired.md) · [Condition JSON](https://errorgram.rmbk.me/errors/query.invalid_or_expired.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Request retry after · request.retry\_after Canonical page: https://errorgram.rmbk.me/errors/request.retry_after/ **Stable ID:** `request.retry_after` · **Evidence:** source derived The server asks the bot to wait before trying again. The response does not identify whether the limit is per chat, per bot, per method or caused by server lifecycle handling. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **429**. - `parameters.retry_after`: a positive safe integer. The structured parameter decides the match; the description may vary. See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `setWebhook`, `close`. ## Possible causes - Flood limiting. - Authorization or startup throttling. - An unfinished query being disposed, including during shutdown. ## Before deciding what to do **Application decision:** schedule bounded retry. **Repeat request:** after server delay and policy check. - Wait at least the supplied delay, coordinate with any framework retry plugin, and bound attempts. Delay parameter: `retry_after`. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts Values extracted into `result.facts`: - `retry_after`: a positive safe integer, from `parameters.retry_after`. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 429, "description": "Too Many Requests: retry after 5", "parameters": { "retry_after": 5 } } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 429, "description": "Too Many Requests: retry after 5", "parameters": { "retry_after": 5, }, } result = classify(response, method='sendMessage') assert result.id == 'request.retry_after' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 429, "description": "Too Many Requests: retry after 5", "parameters": { "retry_after": 5 } }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "request.retry_after") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.RequestRetryAfter` | | aiogram | `errorgram.aiogram.RequestRetryAfter` extends `TelegramRetryAfter` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `request.retry_after` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Query.cpp:120–126](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Query.cpp#L120-L126). Builds both the description and structured retry\_after parameter. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Query.h:238–242](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Query.h#L238-L242). The query deleter also produces this response with a five-second delay. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:17529–17550](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17529-L17550). Flood and authorization paths share the response shape. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Official documentation](https://core.telegram.org/bots/api#responseparameters). Documents retry\_after in seconds. Accessed 2026-09-15. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/request.retry_after.md) · [Condition JSON](https://errorgram.rmbk.me/errors/request.retry_after.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Routing token not served · routing.token\_not\_served Canonical page: https://errorgram.rmbk.me/errors/routing.token_not_served/ **Stable ID:** `routing.token_not_served` · **Evidence:** source derived The token failed the server’s bot-ID or routing check. The same response covers a routing failure and a token-format failure; it does not prove that Telegram revoked the token. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **421**. Exact description: ```text Misdirected Request: forbidden token specified ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getMe`. Relevant to the open-source server's token-range routing; hosted occurrence is unverified. ## Possible causes - The bot ID is outside the server’s configured token range. - The token’s numeric prefix could not be parsed. ## Before deciding what to do **Application decision:** inspect token prefix and server routing. **Repeat request:** after configuration change. - Check token formatting and, when operating a local server, its token-range configuration. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getMe`. ```json { "ok": false, "error_code": 421, "description": "Misdirected Request: forbidden token specified" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 421, "description": "Misdirected Request: forbidden token specified", } result = classify(response, method='getMe') assert result.id == 'routing.token_not_served' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 421, "description": "Misdirected Request: forbidden token specified" }; const result = classify(response, { method: "getMe" }); if (result.status === "matched" && result.id === "routing.token_not_served") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.RoutingTokenNotServed` | | aiogram | `errorgram.aiogram.RoutingTokenNotServed` extends `TelegramAPIError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `routing.token_not_served` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/ClientManager.cpp:78–80](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/ClientManager.cpp#L78-L80). Both sides of the condition emit the same 421 response. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/routing.token_not_served.md) · [Condition JSON](https://errorgram.rmbk.me/errors/routing.token_not_served.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Server restarting · server.restarting Canonical page: https://errorgram.rmbk.me/errors/server.restarting/ **Stable ID:** `server.restarting` · **Evidence:** source derived The bot client is closing for a server restart. An exception wrapper that discarded the original 5xx description cannot recover this distinction from the status alone. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **500**. Exact description: ```text Internal Server Error: restart ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. ## Possible causes - The bot client is closing without taking the logout branches. ## Before deciding what to do **Application decision:** backoff and reassess operation. **Repeat request:** policy dependent. - Apply bounded backoff and evaluate whether repeating the particular operation is safe; do not derive replay safety from a 5xx status alone. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getMe`. ```json { "ok": false, "error_code": 500, "description": "Internal Server Error: restart" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 500, "description": "Internal Server Error: restart", } result = classify(response, method='getMe') assert result.id == 'server.restarting' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 500, "description": "Internal Server Error: restart" }; const result = classify(response, { method: "getMe" }); if (result.status === "matched" && result.id === "server.restarting") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.ServerRestarting` | | aiogram | `errorgram.aiogram.ServerRestarting` extends `RestartingTelegram` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `server.restarting` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:17560–17564](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17560-L17564). The closing error is passed directly to fail\_query by fail\_query\_closing. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/server.restarting.md) · [Condition JSON](https://errorgram.rmbk.me/errors/server.restarting.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Session logged out · session.logged\_out Canonical page: https://errorgram.rmbk.me/errors/session.logged_out/ **Stable ID:** `session.logged_out` · **Evidence:** source derived The bot session has logged out. Not every 400 response begins with Bad Request. This signature alone does not explain why logout was initiated. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Logged out ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. ## Possible causes - The server is completing a bot logout. ## Before deciding what to do **Application decision:** reconcile bot session lifecycle. **Repeat request:** after lifecycle resolution. - Determine whether logout or a server move was intentional before resuming requests. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getMe`. ```json { "ok": false, "error_code": 400, "description": "Logged out" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Logged out", } result = classify(response, method='getMe') assert result.id == 'session.logged_out' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Logged out" }; const result = classify(response, { method: "getMe" }); if (result.status === "matched" && result.id === "session.logged_out") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.SessionLoggedOut` | | aiogram | `errorgram.aiogram.SessionLoggedOut` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `session.logged_out` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:17553–17555](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17553-L17555). Stores a 400 description with no Bad Request prefix. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:17520–17525](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17520-L17525). The direct fail\_query path preserves that description. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/session.logged_out.md) · [Condition JSON](https://errorgram.rmbk.me/errors/session.logged_out.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Text empty · text.empty Canonical page: https://errorgram.rmbk.me/errors/text.empty/ **Stable ID:** `text.empty` · **Evidence:** observed The message text is empty. This validates the message text input; it does not establish a rule for optional media captions. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: message text is empty ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`. ## Possible causes - The text argument is absent or empty. ## Before deciding what to do **Application decision:** supply message text. **Repeat request:** after relevant change. - Provide nonempty text appropriate for the selected method. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: message text is empty" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: message text is empty", } result = classify(response, method='sendMessage') assert result.id == 'text.empty' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: message text is empty" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "text.empty") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.TextEmpty` | | aiogram | `errorgram.aiogram.TextEmpty` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `text.empty` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Recorded observation](https://github.com/uburuntu/errorgram/blob/4314ac1f9d29d105b10e9b537a7643cc65d097aa/observations/2026-09-16.json). sendMessage with empty text returned this description. Accessed 2026-09-16. - [Bot API 10.3 · telegram-bot-api/Client.cpp:12039–12052](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L12039-L12052). Text-message construction rejects empty text before formatting. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13981–13993](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13981-L13993). sendMessage constructs its text with this helper. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/text.empty.md) · [Condition JSON](https://errorgram.rmbk.me/errors/text.empty.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Text too long · text.too\_long Canonical page: https://errorgram.rmbk.me/errors/text.too_long/ **Stable ID:** `text.too_long` · **Evidence:** source derived The text exceeds the limit checked by this response path. The local guard is not the public character limit for every method. Other message and caption limits can produce different descriptions. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Exact description: ```text Bad Request: text is too long ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`, `sendPhoto`. ## Possible causes - Text supplied to the formatting helper exceeds its local byte-size guard. ## Before deciding what to do **Application decision:** shorten text for method. **Repeat request:** after relevant change. - Check the selected method’s text or caption limits and preserve valid formatting when shortening or splitting text. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: text is too long" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: text is too long", } result = classify(response, method='sendMessage') assert result.id == 'text.too_long' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: text is too long" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "text.too_long") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.TextTooLong` | | aiogram | `errorgram.aiogram.TextTooLong` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `text.too_long` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:11955–11958](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L11955-L11958). The formatting helper rejects text.size() greater than 32768 before parsing. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:13800–13803](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L13800-L13803). Method validation errors are passed to the response normalizer. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/text.too_long.md) · [Condition JSON](https://errorgram.rmbk.me/errors/text.too_long.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Updates concurrent poll · updates.concurrent\_poll Canonical page: https://errorgram.rmbk.me/errors/updates.concurrent_poll/ **Stable ID:** `updates.concurrent_poll` · **Evidence:** source derived Another getUpdates request interrupted the pending long poll. Overlapping requests may originate in one process or multiple deployments; the response does not prove how many bot processes exist. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **409**. Exact description: ```text Conflict: terminated by other getUpdates request; make sure that only one bot instance is running ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getUpdates`. ## Possible causes - Overlapping getUpdates requests for the same bot. ## Before deciding what to do **Application decision:** ensure single polling owner. **Repeat request:** after concurrency change. - Stop competing polling loops or establish ownership before resuming. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getUpdates`. ```json { "ok": false, "error_code": 409, "description": "Conflict: terminated by other getUpdates request; make sure that only one bot instance is running" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 409, "description": "Conflict: terminated by other getUpdates request; make sure that only one bot instance is running", } result = classify(response, method='getUpdates') assert result.id == 'updates.concurrent_poll' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 409, "description": "Conflict: terminated by other getUpdates request; make sure that only one bot instance is running" }; const result = classify(response, { method: "getUpdates" }); if (result.status === "matched" && result.id === "updates.concurrent_poll") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.UpdatesConcurrentPoll` | | aiogram | `errorgram.aiogram.UpdatesConcurrentPoll` extends `TelegramConflictError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `updates.concurrent_poll` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:17493–17514](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17493-L17514). The alternate branch emits a different description for termination by setWebhook. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/updates.concurrent_poll.md) · [Condition JSON](https://errorgram.rmbk.me/errors/updates.concurrent_poll.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Updates webhook active · updates.webhook\_active Canonical page: https://errorgram.rmbk.me/errors/updates.webhook_active/ **Stable ID:** `updates.webhook_active` · **Evidence:** source derived Polling was requested while a webhook is active or being configured. This is a different condition from two simultaneous getUpdates requests. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **409**. Exact description: ```text Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `getUpdates`. ## Possible causes - The bot has an active or pending webhook configuration. ## Before deciding what to do **Application decision:** choose update delivery mode. **Repeat request:** after configuration change. - If polling is intended, remove the webhook deliberately; if webhooks are intended, stop polling. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `getUpdates`. ```json { "ok": false, "error_code": 409, "description": "Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 409, "description": "Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first", } result = classify(response, method='getUpdates') assert result.id == 'updates.webhook_active' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 409, "description": "Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first" }; const result = classify(response, { method: "getUpdates" }); if (result.status === "matched" && result.id === "updates.webhook_active") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.UpdatesWebhookActive` | | aiogram | `errorgram.aiogram.UpdatesWebhookActive` extends `TelegramConflictError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `updates.webhook_active` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:16926–16931](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L16926-L16931). Checks configured and pending webhook state before polling. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/updates.webhook_active.md) · [Condition JSON](https://errorgram.rmbk.me/errors/updates.webhook_active.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # User deactivated · user.deactivated Canonical page: https://errorgram.rmbk.me/errors/user.deactivated/ **Stable ID:** `user.deactivated` · **Evidence:** source derived Telegram rejected the operation because the user is deactivated. The response establishes the current rejection; it does not expose account history or a replacement recipient. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **403**. Exact description: ```text Forbidden: user is deactivated ``` See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `sendMessage`, `editMessageText`. ## Possible causes - The target private-chat user is marked deleted. - Telegram reported that the target account is deactivated. ## Before deciding what to do **Application decision:** suspend operations for recipient. **Repeat request:** after access change. - Stop repeating this operation for the recipient unless there is evidence that the target or its availability changed. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts This condition adds no extracted facts; `result.facts` is empty. ## Example Synthetic examples derived from the cited source. API method: `sendMessage`. ```json { "ok": false, "error_code": 403, "description": "Forbidden: user is deactivated" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 403, "description": "Forbidden: user is deactivated", } result = classify(response, method='sendMessage') assert result.id == 'user.deactivated' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 403, "description": "Forbidden: user is deactivated" }; const result = classify(response, { method: "sendMessage" }); if (result.status === "matched" && result.id === "user.deactivated") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.UserDeactivated` | | aiogram | `errorgram.aiogram.UserDeactivated` extends `TelegramForbiddenError` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `user.deactivated` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:8803–8807](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L8803-L8807). Edit or write access to a deleted private-chat user is rejected directly with code 403. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:124–126](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L124-L126). INPUT\_USER\_DEACTIVATED also maps to this exact 403 response. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.cpp:165–205](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L165-L205). Adds the code-specific prefix and lowercases only the initial character of ordinary messages. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/user.deactivated.md) · [Condition JSON](https://errorgram.rmbk.me/errors/user.deactivated.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) --- # Webhook certificate too large · webhook.certificate\_too\_large Canonical page: https://errorgram.rmbk.me/errors/webhook.certificate_too_large/ **Stable ID:** `webhook.certificate_too_large` · **Evidence:** source derived The uploaded webhook certificate exceeds the server’s size limit. The captured size describes the rejected upload; it is not the configured limit or a Telegram media limit. ## When it matches Every field in a rule must match. Alternative rules are joined with OR. Codes below are JSON response fields, not inferred HTTP statuses. - JSON `error_code`: **400**. Description template; literal text must match exactly: ```text Bad Request: certificate size is too big ({size_bytes} bytes) ``` - `size_bytes`: a positive safe integer, captured from the description. See [matching rules](https://errorgram.rmbk.me/matching/) for parameter precedence and unknown or ambiguous results. **Illustrative methods:** `setWebhook`. ## Possible causes - The uploaded certificate file is larger than MAX\_CERTIFICATE\_FILE\_SIZE. ## Before deciding what to do **Application decision:** correct webhook certificate file. **Repeat request:** after payload change. - Verify that the uploaded file is the intended certificate and satisfies this server revision's limit. These are application choices. Errorgram does not retry, suppress the error, or change bot state. ## Facts Values extracted into `result.facts`: - `size_bytes`: a positive safe integer, from `description`. Version-specific metadata is available in `result.entry` under `facts`. These values are catalogue metadata, not measurements from the response. ```json { "verified_limit_bytes": 3145728, "limit_version_source": "server-10.3" } ``` ## Example Synthetic examples derived from the cited source. API method: `setWebhook`. ```json { "ok": false, "error_code": 400, "description": "Bad Request: certificate size is too big (4194304 bytes)" } ``` ### Python ```python from errorgram import classify response = { "ok": False, "error_code": 400, "description": "Bad Request: certificate size is too big (4194304 bytes)", } result = classify(response, method='setWebhook') assert result.id == 'webhook.certificate_too_large' print(result.entry["summary"]) ``` ### JavaScript and TypeScript ```ts import { classify } from "errorgram"; const response = { "ok": false, "error_code": 400, "description": "Bad Request: certificate size is too big (4194304 bytes)" }; const result = classify(response, { method: "setWebhook" }); if (result.status === "matched" && result.id === "webhook.certificate_too_large") { console.log(result.entry.summary); } ``` ## Framework names | Integration | Type or ID | | --- | --- | | Python | `errorgram.WebhookCertificateTooLarge` | | aiogram | `errorgram.aiogram.WebhookCertificateTooLarge` extends `TelegramBadRequest` | | grammY | `EnrichedGrammyError` with `classification.id` equal to `webhook.certificate_too_large` | Enrichment is explicit and keeps framework catch compatibility. Follow the [Python and aiogram guide](https://errorgram.rmbk.me/python/) or [JavaScript, TypeScript, and grammY guide](https://errorgram.rmbk.me/javascript/). ## Evidence - [Bot API 10.3 · telegram-bot-api/Client.cpp:17261–17266](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.cpp#L17261-L17266). The description interpolates the actual file size; one literal string cannot represent all responses. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. - [Bot API 10.3 · telegram-bot-api/Client.h:71](https://github.com/tdlib/telegram-bot-api/blob/e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1/telegram-bot-api/Client.h#L71). The constant is 3 << 20 bytes in this revision. Revision `e3e9dd8e5b3d7ab8537cd5a10dc31d5ffa8f82d1`. Source references identify the reviewed revision, not the first release that introduced this response. ## Data and versions Catalogue `0.1.0` · schema `1.0.0` · reviewed 2026-09-16. [Markdown](https://errorgram.rmbk.me/errors/webhook.certificate_too_large.md) · [Condition JSON](https://errorgram.rmbk.me/errors/webhook.certificate_too_large.json) · [Full catalogue and sources](https://errorgram.rmbk.me/catalogue.json) · [JSON Schema](https://errorgram.rmbk.me/schema.json) ---