openclaw - ✅(Solved) Fix Telegram channel: DM messages with message_thread_id fragment into separate sessions, breaking conversation continuity [1 pull requests, 2 comments, 3 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#75975Fetched 2026-05-03 04:43:38
View on GitHub
Comments
2
Participants
3
Timeline
10
Reactions
2
Timeline (top)
commented ×2cross-referenced ×2mentioned ×2subscribed ×2

In Telegram direct messages (1-on-1 DMs), when an inbound message carries a message_thread_id (which newer Telegram clients automatically attach to reply-with-quote messages), OpenClaw appends :topic:<threadId> to the session key. Each new message_thread_id therefore creates a brand-new isolated session with no memory of the previous turn, even though the user perceives a single continuous DM conversation.

The Matrix channel exposes dm.threadReplies = off to disable this behavior in DMs (see docs/channels/matrix.md lines 577–581, 940). The Telegram channel does not.

Root Cause

In a real overnight workspace (single user, single Telegram DM with the bot, single conceptual conversation), one evening produced 6 distinct session keys across the same continuous user-perceived conversation, because the Telegram client tagged different replies with different message_thread_id values. Each session woke up cold, with the agent immediately apologizing for "losing the thread" and asking the user to re-state context — multiple times in the same hour.

Fix Action

Fix / Workaround

Workaround (current)

PR fix notes

PR #76011: fix(telegram): stop DM message_thread_id from fragmenting sessions

Description (problem / solution / changelog)

Problem

When a user reply-quotes a message in a Telegram DM, Telegram sends a message_thread_id field on the update. The existing code unconditionally used this field to derive a separate thread session key (agent:main:main:thread:<chatId>:<threadId>), fragmenting the DM conversation into isolated sessions that lose all prior context.

This is a regression for any agent that relies on DM conversation continuity — a simple reply-with-quote from the user creates a brand new session with no history.

Solution

Add a dmThreadReplies config option ("off" | "inbound" | "always", default: "off") that controls whether message_thread_id in DMs creates separate sessions:

  • "off" (default): Ignore message_thread_id for session key derivation in DMs. The thread ID is still preserved in the message context for outbound reply targeting, but it no longer splits the session.
  • "inbound" / "always": Use thread IDs for session isolation (legacy behavior).

Config levels

  • Account-level default: channels.telegram.dmThreadReplies
  • Per-DM override: channels.telegram.direct.<chatId>.dmThreadReplies

Per-DM takes precedence over account-level, which defaults to "off".

Design

This follows the same pattern as Matrix channel's existing dm.threadReplies option for consistency across channel implementations.

Changes

FileChange
src/config/types.telegram.tsAdd TelegramDmThreadReplies type, field on TelegramDirectConfig and TelegramAccountConfig
src/config/zod-schema.providers-core.tsAdd Zod schema validation
src/plugin-sdk/config-runtime.tsRe-export new type for extensions
extensions/telegram/src/bot.tsExtract config value, pass to processor
extensions/telegram/src/bot-message.tsThread through deps
extensions/telegram/src/bot-message-context.types.tsAdd to BuildTelegramMessageContextParams
extensions/telegram/src/bot-message-context.tsResolve effective policy, skip thread key when "off"
extensions/telegram/src/bot-message-context.test-harness.tsExpose param for tests
extensions/telegram/src/bot-message-context.dm-threads.test.tsUpdate tests for new default + add opt-in test
CHANGELOG.mdAdd entry

Testing

  • All 18 existing telegram session/thread tests pass
  • New test verifies default behavior (thread ID ignored)
  • New test verifies opt-in "always" behavior (thread ID creates session)
  • Type-checks clean with tsc --noEmit
  • Formatting passes oxfmt --check

Closes #75975

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • extensions/telegram/src/bot-message-context.dm-threads.test.ts (modified, +26/-3)
  • extensions/telegram/src/bot-message-context.test-harness.ts (modified, +2/-0)
  • extensions/telegram/src/bot-message-context.ts (modified, +9/-5)
  • extensions/telegram/src/bot-message-context.types.ts (modified, +3/-0)
  • extensions/telegram/src/bot-message.ts (modified, +2/-0)
  • extensions/telegram/src/bot.ts (modified, +2/-0)
  • src/config/types.telegram.ts (modified, +17/-0)
  • src/config/zod-schema.providers-core.ts (modified, +4/-0)
  • src/plugin-sdk/config-runtime.ts (modified, +1/-0)
RAW_BUFFERClick to expand / collapse

Summary

In Telegram direct messages (1-on-1 DMs), when an inbound message carries a message_thread_id (which newer Telegram clients automatically attach to reply-with-quote messages), OpenClaw appends :topic:<threadId> to the session key. Each new message_thread_id therefore creates a brand-new isolated session with no memory of the previous turn, even though the user perceives a single continuous DM conversation.

The Matrix channel exposes dm.threadReplies = off to disable this behavior in DMs (see docs/channels/matrix.md lines 577–581, 940). The Telegram channel does not.

Documented behavior

docs/channels/telegram.md line 258:

DM messages can carry message_thread_id; OpenClaw routes them with thread-aware session keys and preserves thread ID for replies.

docs/channels/telegram.md line 540:

Template context exposes MessageThreadId and IsForum. DM chats with message_thread_id keep DM routing but use thread-aware session keys.

This is intentional for forum-topic groups (where it's correct), but for 1-on-1 DMs it produces user-visible context loss.

Reproduction

  1. Telegram client: any version recent enough to attach message_thread_id to reply-with-quote messages (observed on iOS Telegram 11.x, late 2025+).
  2. OpenClaw configured with default channels.telegram settings (no threadBindings, no direct.<chatId>.requireTopic, no direct.<chatId>.topics.<id> overrides).
  3. User sends a normal DM, agent replies. User taps "Reply" on the agent's message, types a follow-up.
  4. Telegram attaches a message_thread_id to the user's follow-up.
  5. OpenClaw routes the follow-up to session key agent:<agentId>:main:topic:<threadId> instead of the main DM session.
  6. Each subsequent reply-with-quote that lands in a different message_thread_id creates yet another fragmented session.

Observed impact

In a real overnight workspace (single user, single Telegram DM with the bot, single conceptual conversation), one evening produced 6 distinct session keys across the same continuous user-perceived conversation, because the Telegram client tagged different replies with different message_thread_id values. Each session woke up cold, with the agent immediately apologizing for "losing the thread" and asking the user to re-state context — multiple times in the same hour.

This is the most-reported user complaint we've had against the agent ("you keep forgetting what we were talking about"). The agent isn't forgetting — it's literally a different session each turn.

Expected behavior

In a 1-on-1 DM (chat_type: direct), message_thread_id should be ignored for session-key derivation by default. Threading metadata can still be preserved for outbound reply_to/message_thread_id purposes, but should not split the user's conversation across sessions.

Proposed fix (any one of these is sufficient)

Option 1 — Match Matrix's API (preferred): Add channels.telegram.dm.threadReplies (enum off|inbound|always, default off for DMs to match user expectation). When off in DMs, drop message_thread_id from the session key derivation; keep it only for the outbound replyToMessageId/messageThreadId parameters.

Option 2 — Per-DM override: Honor a channels.telegram.direct.<chatId>.requireTopic = false setting (or new flattenTopics = true) that explicitly merges all message_thread_id values for that DM into the main DM session key.

Option 3 — Default change: In chat_type: direct, never include :topic: in the session key regardless of message_thread_id. (More aggressive, but matches what every user we've talked to actually wants.)

Workaround (current)

Workspace-side: agents must check inbound metadata for topic_id on every turn and proactively read daily memory plus sessions_list / sessions_history to reconstruct context before responding. This adds ~1 turn of latency and ~2k tokens/turn to every DM reply. It works, but it's not a fix — it's an operational tax on every turn until upstream resolves.

Environment

  • OpenClaw 2026.4.29 (commit a448042)
  • Channel: Telegram (long-polling, grammY)
  • Telegram Bot API: standard
  • User Telegram client: iOS, current
  • Workspace: single user, single agent, single DM

Related

  • docs/channels/matrix.md — has the right pattern (dm.threadReplies = off)
  • docs/channels/telegram.md lines 257–258, 540
  • docs/channels/groups.md lines 76–78

extent analysis

TL;DR

To fix the issue of OpenClaw creating a new session for each message_thread_id in 1-on-1 Telegram DMs, add a configuration option to ignore message_thread_id for session-key derivation in DMs.

Guidance

  • Implement one of the proposed fix options: add channels.telegram.dm.threadReplies (default off for DMs), introduce a per-DM override like channels.telegram.direct.<chatId>.requireTopic = false, or change the default behavior to never include :topic: in the session key for chat_type: direct.
  • Verify the fix by checking that the session key remains the same across multiple replies with different message_thread_id values in a 1-on-1 DM conversation.
  • Test the fix with different Telegram client versions and OpenClaw configurations to ensure consistency.
  • Consider implementing a temporary workaround, such as having agents check inbound metadata for topic_id and reconstruct context, until the upstream fix is deployed.

Example

No code snippet is provided as the issue is related to configuration and behavior rather than code implementation.

Notes

The proposed fixes aim to align the behavior of OpenClaw with user expectations in 1-on-1 DMs, while preserving the current behavior for forum-topic groups. The choice of fix depends on the specific requirements and constraints of the OpenClaw system.

Recommendation

Apply a workaround, such as implementing a per-DM override, until a more permanent fix can be deployed, as it provides a flexible solution that can be tailored to specific use cases.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

In a 1-on-1 DM (chat_type: direct), message_thread_id should be ignored for session-key derivation by default. Threading metadata can still be preserved for outbound reply_to/message_thread_id purposes, but should not split the user's conversation across sessions.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Telegram channel: DM messages with message_thread_id fragment into separate sessions, breaking conversation continuity [1 pull requests, 2 comments, 3 participants]