Skip to content

Telegram forum-topic replies can vanish when message_thread_id becomes invalid #79408

@Clausinho

Description

@Clausinho

Summary

Telegram replies sent through the newer bot-message-dispatch.ts delivery path can disappear completely in forum topics when Telegram rejects the topic with 400: Bad Request: message thread not found.

User-visible symptom

  • assistant reply exists in the session log
  • nothing appears in Telegram
  • even the generic fallback message may never appear

Root cause

The newer reply delivery path retries threadless only for DM topics:

  • extensions/telegram/src/bot/delivery.send.ts
    • sendTelegramWithThreadFallback() currently sets:
      • const allowThreadlessRetry = params.thread?.scope === "dm";

That means forum-topic replies sent via:

  • extensions/telegram/src/bot-message-dispatch.ts
  • extensions/telegram/src/bot/delivery.replies.ts
  • extensions/telegram/src/bot/delivery.send.ts

will not retry without message_thread_id when Telegram returns message thread not found.

Why this is a bug

This is inconsistent with other Telegram paths in the repo:

  • extensions/telegram/src/send.ts already retries threadless for forum sends
  • extensions/telegram/src/draft-stream.ts retries preview sends threadless on the same error

So preview delivery can recover, while final reply delivery in forum topics can still fail hard.

Minimal fix

Broaden threadless retry in sendTelegramWithThreadFallback() to include forum topics too.

From:

const allowThreadlessRetry = params.thread?.scope === "dm";

To something like:

const allowThreadlessRetry =
  params.thread?.scope === "dm" || params.thread?.scope === "forum";

Regression test

Update extensions/telegram/src/bot/delivery.test.ts so forum replies:

  • first send with message_thread_id
  • on message thread not found, retry once without it
  • do not log a runtime error when the retry succeeds

Tradeoff

Yes, a threadless retry can land in the base supergroup/general context if the topic is gone. But the repo already accepts that tradeoff in other Telegram send paths, and it is better than total silent failure.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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