Skip to content

Telegram: message_thread_id sent on private DMs causes 'message thread not found' error #12929

@enti-bot

Description

@enti-bot

Bug Description

When OpenClaw sends proactive messages (via cron job delivery or the message tool with action=send) to a private DM chat on Telegram, it fails with:

GrammyError: Call to 'sendMessage' failed! (400: Bad Request: message thread not found)

This also affects sendDocument.

Root Cause

OpenClaw stores the message_id from the last inbound Telegram message as lastThreadId in the session entry. When a proactive send (cron delivery or message tool) resolves its delivery target, it picks up this lastThreadId and passes it as message_thread_id to the Telegram API.

In group chats with topics, message_thread_id is valid and identifies a forum topic. But in private DM chats, Telegram does not support message_thread_id, so the API rejects it with error 400.

Regular replies work fine because they use reply_to_message_id (different parameter), not message_thread_id.

Code Path

  1. deliveryContextFromSession() reads lastThreadId from session entry
  2. resolveSessionDeliveryTarget() propagates it as threadId
  3. resolveAgentDeliveryPlan() sets resolvedThreadId
  4. Final send includes threadId as message_thread_id in the Telegram API call

The lastThreadId is repopulated on every inbound message, so clearing it from sessions.json does not persist.

Expected Behavior

OpenClaw should NOT pass message_thread_id to the Telegram API when the target chat is a private DM (not a group with topics/forum enabled).

Reproduction

  1. Configure OpenClaw with a Telegram channel targeting a private DM chat
  2. Create a cron job with delivery.mode: "announce" targeting that chat
  3. The cron delivery will fail with the thread error
  4. Using the message tool with action=send and a filePath also fails

Environment

  • OpenClaw version: 2026.2.6-3
  • Telegram Bot API via Grammy
  • Private DM chat (not a group/supergroup with topics)

Suggested Fix

When resolving the delivery target for Telegram, check the chat type. If it is a private chat, do not include message_thread_id in the API call. Alternatively, provide a config option to disable thread tracking per channel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    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