Skip to content

fix(telegram): broaden DM-topic retry predicate to handle direct_messages_topic_id rejection #28674

@teknium1

Description

@teknium1

From post-merge audit of PR #28488 (#27937 salvage, route resumed DM topic sends via direct_messages_topic_id).

Bug

_should_retry_without_dm_topic_reply_anchor in gateway/platforms/telegram.py:653 requires reply_to_message_id is not None to fire. That guard is correct for the original anchor-stale case it was built for. But after #27937 added the direct_messages_topic_id fallback path for resumed/synthetic sends without an anchor, there's no retry coverage for the case where Bot API rejects the topic id itself.

Scenario

  • Gateway resumes after a shutdown.
  • Synthetic event has no message_id, no reply anchor.
  • _thread_kwargs_for_send returns {message_thread_id: None, direct_messages_topic_id: <hermes_thread_id>}.
  • Bot API rejects (e.g., topic deleted from Telegram side, or stale binding).
  • _should_retry_without_dm_topic_reply_anchor returns False (no reply_to_message_id) → exception propagates → message lost.

Today this is unlikely because Hermes-created DM topics use the same id Telegram uses for message_thread_id, so they shouldn't reject. But:

  1. Stale bindings (topic deleted on Telegram side after Hermes cached the id) → BadRequest.
  2. Telegram could change the contract; we'd be unprotected.

Proposed fix

Broaden the predicate to ALSO fire when:

  • metadata.get('direct_messages_topic_id') is set, AND
  • Error is BadRequest, AND
  • Error message indicates a topic/thread routing issue (e.g., "message thread not found", "DIRECT_MESSAGES_TOPIC_INVALID", or just any BadRequest involving "topic" / "thread").

Retry path already correctly strips both message_thread_id and direct_messages_topic_id (gateway/platforms/telegram.py:697), so widening the predicate alone is the fix.

Severity

Low likelihood today, moderate impact (synthetic notification lost). Defensive hardening.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Low — cosmetic, nice to havecomp/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