Skip to content

Telegram DM topics now require direct_messages_topic_id; message_thread_id falls back to main DM #79455

@lysopen

Description

@lysopen

Summary

Telegram DM/private-chat topics stopped receiving OpenClaw replies and deliveries around 2026-05-08 evening. OpenClaw still resolves the inbound DM topic route/session, but outbound delivery uses message_thread_id, which Telegram now rejects for private DM topics with:

400 Bad Request: message thread not found

A direct Telegram Bot API probe shows that the same topic id succeeds when sent as direct_messages_topic_id instead of message_thread_id.

This appears related to #79448, but that issue focuses on fallback delivery status being reported as delivered. This report focuses on the likely root routing/API field mismatch for Telegram DM topics.

Environment

  • OpenClaw versions tested:
    • 2026.5.7 initially
    • rolled back to 2026.5.4 and reproduced the same behavior
  • OS: Linux / WSL2
  • Node: v22.22.1
  • Telegram chat type: private DM with topics/threaded mode enabled
  • Telegram provider mode: polling
  • channels.telegram.dm.threadReplies tested with both:
    • inbound
    • always

User-visible symptom

  1. Inbound messages from a Telegram DM topic still reach OpenClaw.
  2. OpenClaw creates/uses a thread-scoped session key like:
agent:main:telegram:direct:<chat_id>:thread:<chat_id>:<topic_id>
  1. Assistant replies are generated normally.
  2. Replies do not appear in the DM topic screen.
  3. Replies appear in the Telegram “All” / main DM view instead.

Timeline observed

  • Earlier on 2026-05-08, Telegram DM topic replies were working.
  • Later the same evening, replies started landing only in the main/all DM view.
  • Restarting Gateway did not fix it.
  • Changing dm.threadReplies from inbound to always did not fix it.
  • Rolling back from OpenClaw 2026.5.7 to 2026.5.4 did not fix it.

Reproduction / diagnostics performed

1. OpenClaw message tool with explicit topic/thread target

Sending through OpenClaw to a DM topic target or with explicit threadId succeeds from OpenClaw's perspective, but the message lands in the main/all DM view.

Examples tested:

target = <chat_id>:topic:<topic_id>

and:

target = <chat_id>
threadId = <topic_id>

Both returned successful message ids, but Telegram displayed the messages outside the topic.

2. Raw Telegram Bot API probe with message_thread_id

Direct Bot API call, token omitted:

{
  "chat_id": "<chat_id>",
  "text": "raw message_thread_id test",
  "message_thread_id": 42159
}

Telegram response:

{
  "http": 400,
  "ok": false,
  "error_code": 400,
  "description": "Bad Request: message thread not found"
}

The same failure was observed for the previous topic id as well as a freshly-created topic id.

3. Raw Telegram Bot API probe with direct_messages_topic_id

Direct Bot API call, same chat/topic, token omitted:

{
  "chat_id": "<chat_id>",
  "text": "raw direct_messages_topic_id test",
  "direct_messages_topic_id": 42159
}

Telegram response:

{
  "http": 200,
  "ok": true,
  "message_id": 26887,
  "chat_id": "<chat_id>"
}

This strongly suggests that Telegram private/DM topics now require direct_messages_topic_id for outbound sends, while OpenClaw currently uses message_thread_id for DM topic sends.

Gateway log evidence

OpenClaw logs show the current fallback behavior:

telegram sendMessage: message thread not found; retrying without message_thread_id
telegram sendMessage ok chat=<chat_id> message=<message_id>

So OpenClaw first tries topic delivery, Telegram rejects it, then OpenClaw retries without the thread/topic field. The retry succeeds but lands in the main/all DM view.

Expected behavior

For Telegram private DM topics, OpenClaw should send outbound messages using the Telegram Bot API field that Telegram accepts for private direct-message topics:

{
  "direct_messages_topic_id": <topic_id>
}

For Telegram forum/group topics, OpenClaw should continue using:

{
  "message_thread_id": <topic_id>
}

Actual behavior

OpenClaw appears to send DM topic outbound messages using message_thread_id, causing Telegram to return:

400 Bad Request: message thread not found

OpenClaw then falls back to a bare DM send, making the message visible only in the main/all DM view.

Why this may have started suddenly

This matches #79448's timeline: Telegram seems to have stopped accepting message_thread_id for private DM topics sometime on 2026-05-08. In our environment, the behavior changed the same day: it worked earlier, then started failing later in the evening without local config changes that explain the Telegram API rejection.

Suggested fix

In the Telegram outbound/send parameter builder, distinguish DM/private topics from forum/group topics:

if (thread.scope === "dm") {
  return normalized > 0 ? { direct_messages_topic_id: normalized } : undefined;
}

if (thread.scope === "forum") {
  return normalized > 1 ? { message_thread_id: normalized } : undefined;
}

The exact field name should be verified against the current Telegram Bot API schema, but live probing indicates direct_messages_topic_id is accepted while message_thread_id is rejected for private DM topics.

Related issues / PRs

Workaround

Current workaround is to stop relying on Telegram DM topics and send to the bare DM chat. This avoids invisible/misleading topic routing, but does not preserve topic separation.

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