Skip to content

Telegram streaming ignores 429 retry_after, floods API on rate limit #7360

@flobo3

Description

@flobo3

Bug

When the Telegram Bot API returns a 429 Too Many Requests error during streaming message edits, the Agno Telegram interface ignores the retry_after value and immediately retries on every subsequent streaming chunk. This causes a flood of repeated 429 errors:

WARNING  Failed to edit message: A request to the Telegram API was unsuccessful. Error code: 429. Description: Too Many Requests: retry after 33
WARNING  Failed to edit message: A request to the Telegram API was unsuccessful. Error code: 429. Description: Too Many Requests: retry after 32
WARNING  Failed to edit message: A request to the Telegram API was unsuccessful. Error code: 429. Description: Too Many Requests: retry after 32
...

Expected behavior

The Telegram interface should parse the retry_after value from the 429 response and pause all edit attempts for that duration instead of hammering the API.

Root cause

Two locations in the Telegram interface catch exceptions from edit_message_text but do not handle 429 specifically:

  1. state.pyStreamState._edit(): Catches all exceptions, logs a warning, but does not extract retry_after or pause subsequent edits.

  2. events.py_on_run_content(): Catches exceptions from send_or_edit(), logs "Stream edit failed (will retry on next chunk)", and continues — causing the same failed request on every streaming chunk (~1 per second).

Telegram API response format

{"ok": false, "error_code": 429, "description": "Too Many Requests: retry after 33", "parameters": {"retry_after": 33}}

The retry_after value is also present in the exception message string (via pyTelegramBotAPI's ApiTelegramException).

Proposed fix

  • Parse retry_after from 429 error messages using a regex (re.compile(r"retry after (\d+)", re.IGNORECASE))
  • Add a _rate_limited_until monotonic timestamp to StreamState
  • Skip edit attempts in send_or_edit() and _edit() while the hold is active
  • Set hold in both _edit() and _on_run_content() when 429 is detected

Environment

  • Agno version: latest (main branch, commit 240076c)
  • pyTelegramBotAPI (installed via agno[telegram])
  • Trigger: streaming mode in a Telegram supergroup with topics

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions