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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions