Skip to content

fix(telegram): omit message_thread_id for private chats to prevent silent message drops#17433

Closed
widingmarcus-cyber wants to merge 2 commits intoopenclaw:mainfrom
widingmarcus-cyber:fix/telegram-thread-id-private-chats-17242
Closed

fix(telegram): omit message_thread_id for private chats to prevent silent message drops#17433
widingmarcus-cyber wants to merge 2 commits intoopenclaw:mainfrom
widingmarcus-cyber:fix/telegram-thread-id-private-chats-17242

Conversation

@widingmarcus-cyber
Copy link
Contributor

@widingmarcus-cyber widingmarcus-cyber commented Feb 15, 2026

fix(telegram): omit message_thread_id for private chats

Fixes #17242

Problem

When delivering messages to Telegram private chats, the outbound send functions hardcode scope: 'forum' in the thread spec:

// Before:
const threadSpec = messageThreadId != null
  ? { id: messageThreadId, scope: "forum" as const }
  : undefined;

Private chats (positive chatId) don't support forum topics. Telegram rejects the API call with 400: Bad Request: message thread not found, and the message is silently dropped — the user sees blue checkmarks but the agent never receives/sends the message.

From the bug report: 111 failures over 4 days (81 on Feb 11 alone).

Root Cause

sendMessageTelegram, sendStickerTelegram, and sendPollTelegram all construct the thread spec with scope: 'forum' regardless of whether the chat is a private chat or a group. The existing buildTelegramThreadParams() helper already correctly filters out scope: 'dm', but it never sees scope: 'dm' because the callers always pass 'forum'.

Fix

Add inferThreadScope(chatId) helper that determines scope from the chatId:

  • Positive numeric IDs'dm' (private chat)
  • @-usernames'dm' (private chat / channel)
  • Negative numeric IDs'forum' (group/supergroup, may be forum)
// After:
const threadSpec = messageThreadId != null
  ? { id: messageThreadId, scope: inferThreadScope(chatId) }
  : undefined;

This lets the existing buildTelegramThreadParams() guard properly omit message_thread_id for private chats.

Changed Files

File Change
src/telegram/send.ts Add inferThreadScope(); fix all 3 send functions
src/telegram/send.returns-undefined-empty-input.test.ts Update retry tests to use group chatIds
src/telegram/send.poll.test.ts Update retry test + add private chat assertion

Testing

  • All 447 Telegram tests pass
  • Added new test: omits message_thread_id for private chats (positive chatId)
  • Existing retry tests updated to use negative chatIds (groups)

Greptile Summary

Fixes silent message drops when sending to Telegram private chats by adding inferThreadScope(chatId) to correctly determine whether message_thread_id should be included in API calls. Private chats (positive numeric IDs) get scope: "dm", which causes the existing buildTelegramThreadParams() guard to omit message_thread_id — preventing the Telegram 400 "message thread not found" error.

  • Adds inferThreadScope() helper in src/telegram/send.ts and applies it consistently to all three send functions (sendMessageTelegram, sendStickerTelegram, sendPollTelegram)
  • Updates existing retry tests to use negative (group) chatIds, since private chats no longer include message_thread_id at all
  • Adds a new test verifying message_thread_id is omitted for private chats
  • Includes a separate test stabilization fix for src/web/media.test.ts (tmpdir HOME overlap)
  • Issue: openclaw-2026-02-15.log — a test log file was accidentally committed and should be removed

Confidence Score: 4/5

  • The core logic fix is correct and well-tested, but an accidental log file was committed
  • The inferThreadScope fix is straightforward, integrates cleanly with the existing buildTelegramThreadParams() guard, and is applied consistently to all three send functions. Tests are updated appropriately. Score is 4 instead of 5 solely because an unrelated log file (openclaw-2026-02-15.log) was accidentally committed.
  • openclaw-2026-02-15.log should be removed from the commit — it's an accidentally committed test log file.

Last reviewed commit: 5c5de82

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines 174 to 176
// @-usernames always resolve to private chats or channels; treat as dm.
if (trimmed.startsWith("@")) {
return "dm";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@-usernames can also be public groups/supergroups

The comment says "@-usernames always resolve to private chats or channels" but in Telegram, @-usernames can also refer to public supergroups — which can have forum topics enabled. If someone sends to a public forum group via @groupname with a messageThreadId, this would incorrectly classify it as "dm" and suppress the message_thread_id.

In practice this is unlikely to cause issues since the main outbound path uses numeric chat IDs from session routing (negative for groups), and normalizeChatId only produces @-prefixed values for manual/CLI sends. But the comment is misleading and this could become a subtle bug if the code path is used differently in the future.

Consider updating the comment to acknowledge this limitation, or handling this case if public forum groups addressed by username is a supported use case.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/telegram/send.ts
Line: 174:176

Comment:
**`@`-usernames can also be public groups/supergroups**

The comment says "`@`-usernames always resolve to private chats or channels" but in Telegram, `@`-usernames can also refer to public supergroups — which *can* have forum topics enabled. If someone sends to a public forum group via `@groupname` with a `messageThreadId`, this would incorrectly classify it as `"dm"` and suppress the `message_thread_id`.

In practice this is unlikely to cause issues since the main outbound path uses numeric chat IDs from session routing (negative for groups), and `normalizeChatId` only produces `@`-prefixed values for manual/CLI sends. But the comment is misleading and this could become a subtle bug if the code path is used differently in the future.

Consider updating the comment to acknowledge this limitation, or handling this case if public forum groups addressed by username is a supported use case.

How can I resolve this? If you propose a fix, please make it concise.

@widingmarcus-cyber widingmarcus-cyber force-pushed the fix/telegram-thread-id-private-chats-17242 branch from 7154157 to 6ec4fe6 Compare February 15, 2026 19:17
@openclaw-barnacle openclaw-barnacle bot added channel: telegram Channel integration: telegram size: S labels Feb 15, 2026
The 'rejects default OpenClaw state per-agent workspace-* roots'
test fails in CI because the test harness sets HOME to a temp
directory under os.tmpdir() (e.g. /tmp/openclaw-test-home-xC06Jb).

Since os.tmpdir() (/tmp) is a default allowed media root, ALL paths
under the test HOME directory match the tmpdir root, causing the
test to resolve instead of reject.

Fix: pin OPENCLAW_STATE_DIR to an absolute path outside /tmp
(/var/openclaw-guard-reject-test) for the duration of the test,
ensuring no default root accidentally matches the workspace-* path.

This is the same pattern steipete used in be9b5ce for the 'web
media loading' describe block, but was missing from the separate
'local media root guard' describe block.
…lent message drops

The outbound send functions in send.ts hardcode scope: 'forum' when
constructing the TelegramThreadSpec for message_thread_id, regardless
of chat type. Private chats (positive numeric chatId) don't support
forum topics, so Telegram rejects the API call with 400 'message
thread not found', silently dropping the message.

Add an inferThreadScope() helper that determines the thread scope from
the chatId:
- Positive numeric IDs and @-usernames → 'dm' (private chat)
- Negative numeric IDs → 'forum' (group/supergroup)

This allows the existing buildTelegramThreadParams() guard (which
already filters scope='dm') to properly omit message_thread_id for
private chats.

All three outbound send paths are fixed:
- sendMessageTelegram (text + media)
- sendStickerTelegram
- sendPollTelegram

Tests updated to use negative chatIds for forum retry tests, and a
new test added to verify private chats never include message_thread_id.

Fixes openclaw#17242
@widingmarcus-cyber widingmarcus-cyber force-pushed the fix/telegram-thread-id-private-chats-17242 branch from 6ec4fe6 to 5c5de82 Compare February 15, 2026 19:54
@openclaw-barnacle openclaw-barnacle bot added the channel: whatsapp-web Channel integration: whatsapp-web label Feb 15, 2026
@steipete steipete closed this Feb 16, 2026
@steipete steipete reopened this Feb 17, 2026
Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +1 to +38
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:34.771Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:34.776Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:34.778Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:34.778Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=true (env:OPENCLAW_TELEGRAM_ENABLE_AUTO_SELECT_FAMILY)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:34.779Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:34.779Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=true (config)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:34.781Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:34.781Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (env:OPENCLAW_TELEGRAM_DISABLE_AUTO_SELECT_FAMILY)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:34.781Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:34.782Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.090Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.095Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.092Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.095Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.092Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.097Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.092Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.097Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: can't parse entities: Can't find end of the entity","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.106Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.106Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 9","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.109Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.109Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 9","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.114Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.114Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: chat not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.119Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.119Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: chat not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.122Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.122Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: chat not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.125Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.126Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.127Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.127Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: message thread not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.136Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.136Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram message failed: 400: Bad Request: message thread not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.139Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.139Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram photo failed: 400: Bad Request: message thread not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:36.149Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:36.149Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:37.005Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:37.008Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram editMessage failed: 400: Bad Request: can't parse entities","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:37.018Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:37.018Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.936Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.939Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.945Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.948Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.945Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.949Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.949Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.952Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.954Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.958Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.953Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.960Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.954Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.960Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.957Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.962Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.958Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.966Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:39.980Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:39.984Z"}
{"0":"{\"module\":\"telegram-auto-reply\"}","1":{"chatId":"1234","senderUserId":"999","username":"random","matchKey":"none","matchSource":"none"},"2":"telegram pairing request","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"module\":\"telegram-auto-reply\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.000Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/telegram/bot-message-context.ts:283:22","fileName":"bot-message-context.ts","fileNameWithLine":"bot-message-context.ts:283","fileColumn":"22","fileLine":"283","filePath":"src/telegram/bot-message-context.ts","filePathWithLine":"src/telegram/bot-message-context.ts:283","method":"buildTelegramMessageContext"}},"time":"2026-02-15T19:17:40.002Z"}
{"0":"{\"module\":\"telegram-auto-reply\"}","1":{"chatId":"1234","senderUserId":"999","username":"random","matchKey":"none","matchSource":"none"},"2":"telegram pairing request","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"module\":\"telegram-auto-reply\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.004Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/telegram/bot-message-context.ts:283:22","fileName":"bot-message-context.ts","fileNameWithLine":"bot-message-context.ts:283","fileColumn":"22","fileLine":"283","filePath":"src/telegram/bot-message-context.ts","filePathWithLine":"src/telegram/bot-message-context.ts:283","method":"buildTelegramMessageContext"}},"time":"2026-02-15T19:17:40.005Z"}
{"0":"{\"module\":\"telegram-auto-reply\"}","1":{"chatId":7,"reason":"no-mention"},"2":"skipping group message","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"module\":\"telegram-auto-reply\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.010Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/telegram/bot-message-context.ts:486:14","fileName":"bot-message-context.ts","fileNameWithLine":"bot-message-context.ts:486","fileColumn":"14","fileLine":"486","filePath":"src/telegram/bot-message-context.ts","filePathWithLine":"src/telegram/bot-message-context.ts:486","method":"buildTelegramMessageContext"}},"time":"2026-02-15T19:17:40.013Z"}
{"0":"{\"module\":\"telegram-auto-reply\"}","1":{"chatId":456,"title":"Ops","reason":"not-allowed"},"2":"skipping group message","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"module\":\"telegram-auto-reply\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.017Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/telegram/bot-handlers.ts:787:18","fileName":"bot-handlers.ts","fileNameWithLine":"bot-handlers.ts:787","fileColumn":"18","fileLine":"787","filePath":"src/telegram/bot-handlers.ts","filePathWithLine":"src/telegram/bot-handlers.ts:787"}},"time":"2026-02-15T19:17:40.019Z"}
{"0":"{\"module\":\"telegram-auto-reply\"}","1":{"chatId":123,"reason":"no-mention"},"2":"skipping group message","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"module\":\"telegram-auto-reply\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.021Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/telegram/bot-message-context.ts:486:14","fileName":"bot-message-context.ts","fileNameWithLine":"bot-message-context.ts:486","fileColumn":"14","fileLine":"486","filePath":"src/telegram/bot-message-context.ts","filePathWithLine":"src/telegram/bot-message-context.ts:486","method":"buildTelegramMessageContext"}},"time":"2026-02-15T19:17:40.022Z"}
{"0":"{\"subsystem\":\"telegram/network\"}","1":"telegram: autoSelectFamily=false (default-node22)","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/network\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.531Z","logLevelId":3,"logLevelName":"INFO","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:40.534Z"}
{"0":"{\"subsystem\":\"telegram/api\"}","1":"telegram poll failed: 400: Bad Request: message thread not found","_meta":{"runtime":"node","runtimeVersion":"22.22.0","hostname":"unknown","name":"{\"subsystem\":\"telegram/api\"}","parentNames":["openclaw"],"date":"2026-02-15T19:17:40.537Z","logLevelId":5,"logLevelName":"ERROR","path":{"fullFilePath":"/tmp/openclaw/src/logging/subsystem.ts:226:12","fileName":"subsystem.ts","fileNameWithLine":"subsystem.ts:226","fileColumn":"12","fileLine":"226","filePath":"src/logging/subsystem.ts","filePathWithLine":"src/logging/subsystem.ts:226","method":"logToFile"}},"time":"2026-02-15T19:17:40.538Z"}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Accidentally committed log file

This test log file appears to have been committed by accident. It contains runtime log output (Telegram API errors, network config, pairing requests) that shouldn't be tracked in version control. Please remove this file from the commit.

Prompt To Fix With AI
This is a comment left during a code review.
Path: openclaw-2026-02-15.log
Line: 1:38

Comment:
**Accidentally committed log file**

This test log file appears to have been committed by accident. It contains runtime log output (Telegram API errors, network config, pairing requests) that shouldn't be tracked in version control. Please remove this file from the commit.

How can I resolve this? If you propose a fix, please make it concise.

@Lukavyi
Copy link
Contributor

Lukavyi commented Feb 17, 2026

⚠️ This PR will break Telegram DM topics.

Private chats with bots do support forum topics since Bot API 9.3 (December 31, 2025). The has_topics_enabled field on the User class indicates when this is active. Suppressing message_thread_id for all private chats breaks topic routing — messages land in General instead of the correct topic.

This exact pattern has already broken DM topics 3 times in the last 3 weeks (commits 9154971, cc0bfa0f3, b4a90bb74). See #18974 for the full timeline.

The correct approach: check has_topics_enabled (or the resolved scope === "forum") instead of blanket-suppressing based on chatId > 0.

@widingmarcus-cyber
Copy link
Contributor Author

You're absolutely right — thanks for the thorough review.

I wasn't aware that Bot API 9.3 added forum topic support for private chats via has_topics_enabled. The blanket suppression based on chatId > 0 is the wrong approach.

The correct fix should check has_topics_enabled (or the resolved scope === "forum") rather than inferring from the chatId sign. I'll close this PR.

Thanks for linking #18974 — helpful to see the full timeline of this recurring issue.

@widingmarcus-cyber
Copy link
Contributor Author

Closing per Lukavyi's feedback. The chatId > 0 heuristic doesn't account for Bot API 9.3's private chat forum topics. A proper fix needs to check has_topics_enabled on the User/Chat object.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: telegram Channel integration: telegram channel: whatsapp-web Channel integration: whatsapp-web size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Telegram: message_thread_id sent in private chats causes 400 "message thread not found", silently drops messages

3 participants

Comments