Description
When a Telegram bot has topics enabled in DMs (has_topics_enabled: true), the message tool (action=send) sends media and text to the General topic instead of the current session topic.
Root Cause
The message tool receives toolContext.currentThreadTs from the session context (set via buildToolContext in channels/dock.js), but this value is never mapped to params.threadId.
The Telegram plugin action handler (readTelegramSendParams in channels/plugins/actions/telegram.ts) reads params.threadId, which is only set if the caller explicitly passes it. The toolContext.currentThreadTs is not injected into params.
Auto-reply works correctly because it uses a different code path (sendMessageTelegram directly with messageThreadId from session context).
Flow
- Session has
MessageThreadId (e.g., 994409)
buildToolContext maps it to currentThreadTs: "994409"
message tool passes toolContext to runMessageAction
handleSendAction reads params.threadId → undefined (not set from toolContext)
executeSendAction → dispatchChannelMessageAction → Telegram plugin
- Plugin reads
params.threadId → undefined
sendMessageTelegram called without messageThreadId
- Message lands in General topic instead of current topic
Expected
message tool should inject toolContext.currentThreadTs into params.threadId (when not explicitly provided) so that Telegram plugin sends to the correct topic.
Reproduction
- Enable topics on a Telegram bot DM
- Start a conversation in a non-General topic
- Use the
message tool to send media (e.g., message(action=send, target=<chat_id>, media=/path/to/image.jpg))
- Image arrives in General topic, not the current topic
Environment
- Clawdbot version: 2026.1.24-3
- Telegram Bot API with
has_topics_enabled: true in DMs
- Grammy library
lobster-biscuit
Description
When a Telegram bot has topics enabled in DMs (
has_topics_enabled: true), themessagetool (action=send) sends media and text to the General topic instead of the current session topic.Root Cause
The
messagetool receivestoolContext.currentThreadTsfrom the session context (set viabuildToolContextinchannels/dock.js), but this value is never mapped toparams.threadId.The Telegram plugin action handler (
readTelegramSendParamsinchannels/plugins/actions/telegram.ts) readsparams.threadId, which is only set if the caller explicitly passes it. ThetoolContext.currentThreadTsis not injected intoparams.Auto-reply works correctly because it uses a different code path (
sendMessageTelegramdirectly withmessageThreadIdfrom session context).Flow
MessageThreadId(e.g.,994409)buildToolContextmaps it tocurrentThreadTs: "994409"messagetool passestoolContexttorunMessageActionhandleSendActionreadsparams.threadId→undefined(not set from toolContext)executeSendAction→dispatchChannelMessageAction→ Telegram pluginparams.threadId→undefinedsendMessageTelegramcalled withoutmessageThreadIdExpected
messagetool should injecttoolContext.currentThreadTsintoparams.threadId(when not explicitly provided) so that Telegram plugin sends to the correct topic.Reproduction
messagetool to send media (e.g.,message(action=send, target=<chat_id>, media=/path/to/image.jpg))Environment
has_topics_enabled: truein DMslobster-biscuit