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
Bug Description
When replying to messages in a non-forum Telegram DM, the Telegram API sets
message.message_thread_idon incoming messages (indicating the reply chain). The gateway captures this and passes it through asthread_idin metadata, then uses it in allsend_message()calls.Since the DM chat is not a forum/topic-enabled chat, Telegram rejects
message_thread_idwithBadRequest: Message thread not found.Impact
Root Cause
_build_message_event()intelegram.pycapturesmessage.message_thread_idunconditionally and passes it tobuild_source(). In non-forum DMs, Telegram sets this field on replies to indicate the reply chain, but it cannot be used as amessage_thread_idparameter when sending.The
send()method then passes this toself._bot.send_message(message_thread_id=...), which fails. The error is caught by the_NetErrretry 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:2. Graceful fallback in
send()When
send()gets "Message thread not found", retry withoutmessage_thread_idinstead of retrying with the same broken value:Environment