Skip to content

[Bug]: Telegram DM sends fail with 'Message thread not found' — spurious thread_id from reply chains #3206

@MacroAnarchy

Description

@MacroAnarchy

Bug Description

When replying to messages in a non-forum Telegram DM, the Telegram API sets message.message_thread_id on incoming messages (indicating the reply chain). The gateway captures this and passes it through as thread_id in metadata, then uses it in all send_message() calls.

Since the DM chat is not a forum/topic-enabled chat, Telegram rejects message_thread_id with BadRequest: Message thread not found.

Impact

  • Streaming completely breaks — every streaming chunk fails with 3 retries (exponential backoff), causing massive delays and dropped messages
  • All send types affected — text, voice, photo, image, animation, typing indicators
  • 1000+ errors per session in gateway.log, flooding logs

Root Cause

_build_message_event() in telegram.py captures message.message_thread_id unconditionally and passes it to build_source(). In non-forum DMs, Telegram sets this field on replies to indicate the reply chain, but it cannot be used as a message_thread_id parameter when sending.

The send() method then passes this to self._bot.send_message(message_thread_id=...), which fails. The error is caught by the _NetErr retry loop, but all 3 retries use the same broken thread_id.

Suggested Fix

Two-layer defense:

1. Drop unresolved DM thread_ids at the source (_build_message_event)

In _build_message_event(), after attempting to resolve the DM topic, if no topic was found, drop the thread_id:

# If no DM topic was resolved, Telegram may have sent a spurious
# thread_id (e.g. reply-chain id in a non-forum DM). Drop it so
# downstream send calls don't fail with "Message thread not found".
if not chat_topic:
    thread_id_str = None

2. Graceful fallback in send()

When send() gets "Message thread not found", retry without message_thread_id instead of retrying with the same broken value:

effective_thread_id = int(thread_id) if thread_id else None
for _send_attempt in range(3):
    try:
        ...
    except Exception as err:
        if "thread not found" in str(err).lower() and effective_thread_id is not None:
            effective_thread_id = None
            continue
        raise

Environment

  • Hermes v0.4.0
  • python-telegram-bot
  • Telegram DM (non-forum, non-topic chat)
  • Messages that are replies to previous messages trigger the issue

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High — major feature broken, no workaroundcomp/gatewayGateway runner, session dispatch, deliveryplatform/telegramTelegram bot adaptertype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions