openclaw - ✅(Solved) Fix Telegram group chat: model responses silently dropped when message tool not called [1 pull requests, 1 comments, 2 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#84327Fetched 2026-05-20 03:41:29
View on GitHub
Comments
1
Participants
2
Timeline
4
Reactions
1
Author
Timeline (top)
labeled ×2commented ×1cross-referenced ×1

In Telegram group chats, when the model generates a text response but does not call the message tool, the response is silently discarded and the user sees nothing. This happens because sourceReplyDeliveryMode: "message_tool_only" (the default for group/channel chats) causes dispatch-from-config.ts to suppress all payloads that lack deliverDespiteSourceReplySuppression metadata.

The model intermittently skips calling the message tool — especially after long idle periods when the Anthropic prompt cache goes cold — even though the delivery hint ("Delivery: to send a message, use the message tool.") is present in every prompt.

Error Message

  1. The response is silently dropped — no error, no delivery, no log indication

Root Cause

Two-part problem:

  1. Model behavior: claude-opus-4-7 intermittently generates direct text without calling the message tool, particularly after long idle gaps.

  2. Runtime suppression: In dispatch-from-config.ts (~line 1608):

    if (suppressDelivery && !shouldDeliverDespiteSourceReplySuppression(reply)) {
        continue; // payload silently skipped
    }

    When sourceReplyDeliveryMode is "message_tool_only", suppressDelivery is true. Only payloads marked with deliverDespiteSourceReplySuppression (set by markReplyPayloadForSourceSuppressionDelivery) survive. Plain assistant text payloads from buildEmbeddedRunPayloads never get this flag, so they are silently dropped.

Fix Action

Fix / Workaround

In Telegram group chats, when the model generates a text response but does not call the message tool, the response is silently discarded and the user sees nothing. This happens because sourceReplyDeliveryMode: "message_tool_only" (the default for group/channel chats) causes dispatch-from-config.ts to suppress all payloads that lack deliverDespiteSourceReplySuppression metadata.

  1. Runtime suppression: In dispatch-from-config.ts (~line 1608):
    if (suppressDelivery && !shouldDeliverDespiteSourceReplySuppression(reply)) {
        continue; // payload silently skipped
    }
    When sourceReplyDeliveryMode is "message_tool_only", suppressDelivery is true. Only payloads marked with deliverDespiteSourceReplySuppression (set by markReplyPayloadForSourceSuppressionDelivery) survive. Plain assistant text payloads from buildEmbeddedRunPayloads never get this flag, so they are silently dropped.

In agent-runner.ts, after the agent run completes: when sourceReplyDeliveryMode is "message_tool_only" and the model produced text payloads but no side-effect delivery occurred (no message tool, no block streaming), mark those payloads with deliverDespiteSourceReplySuppression so they bypass the dispatch suppression and the user still sees the response.

PR fix notes

PR #84328: fix(agent-runner): deliver assistant text as fallback when model skips message tool

Description (problem / solution / changelog)

Summary

Fixes #84327

When sourceReplyDeliveryMode is "message_tool_only" (the default for Telegram group/channel chats), model responses were silently dropped if the model generated text without calling the message tool. This marks those payloads for fallback delivery so the user always sees the response.

Problem

The dispatch layer in dispatch-from-config.ts suppresses all reply payloads that lack deliverDespiteSourceReplySuppression metadata when suppressDelivery is true. Payloads from the message tool get this flag via markReplyPayloadForSourceSuppressionDelivery, but plain assistant text payloads from buildEmbeddedRunPayloads never do.

When the model intermittently skips calling the message tool (observed after long idle periods when the Anthropic prompt cache goes cold), the response text is generated but silently discarded at the dispatch layer.

Fix

In agent-runner.ts, after the agent run completes: if sourceReplyDeliveryMode is "message_tool_only", the model produced text payloads, and no side-effect delivery occurred (no message tool call, no block streaming, no cron adds), mark those payloads with deliverDespiteSourceReplySuppression so they bypass the dispatch suppression.

Uses the existing hasSuccessfulSideEffectDelivery helper so the fallback only activates when no other delivery path succeeded.

Real behavior proof

Tested on a live Telegram bot (OpenClaw v2026.5.12, claude-opus-4-7 via Anthropic API, group chat with queue mode steer).

Before fix — three consecutive turns with trajectory evidence:

Time (UTC)outputTokenstoolMetasdidSendassistantTextsmessagingToolSentTexts
20:16196[]falseFull relevant response about meal planning[]
20:1796[]false"Hey — did you see the lunch rec?"[]
20:1956[]falseShortened repeat of lunch recommendation[]

All three responses were silently discarded. User saw nothing.

After fix — deployed the fix and restarted gateway:

Time (UTC)outputTokenstoolMetasdidSendassistantTextsdelivered?
21:1911[]false"Pong. Here."Yes — delivered to Telegram

Same pattern (model skipped message tool), but the fallback delivery kicked in and the user received the response.

What was not tested: Block streaming interaction (block streaming was enabled but the model didn't stream in the broken turns). The fix checks hasSuccessfulSideEffectDelivery which covers block streaming, so there should be no double-delivery when block streaming succeeds.

Verification

pnpm test src/auto-reply/reply/agent-runner-payloads.test.ts     # 36 passed
pnpm test src/auto-reply/reply/agent-runner-execution.test.ts    # 72 passed
pnpm test src/auto-reply/reply/agent-runner-direct-runtime-config.test.ts  # 5 passed
pnpm test src/auto-reply/reply/agent-runner.misc.runreplyagent.test.ts     # 38 passed
pnpm test src/auto-reply/reply/dispatch-from-config.test.ts      # 107 passed
pnpm test src/auto-reply/reply/source-reply-delivery-mode.test.ts # 17 passed
pnpm build  # clean

🤖 AI-assisted: diagnosis and fix authored with Claude Code (Opus 4.6). Human confirmed the fix works via live Telegram testing.

Changed files

  • src/auto-reply/reply/agent-runner.ts (modified, +25/-0)

Code Example

if (suppressDelivery && !shouldDeliverDespiteSourceReplySuppression(reply)) {
       continue; // payload silently skipped
   }
RAW_BUFFERClick to expand / collapse

Summary

In Telegram group chats, when the model generates a text response but does not call the message tool, the response is silently discarded and the user sees nothing. This happens because sourceReplyDeliveryMode: "message_tool_only" (the default for group/channel chats) causes dispatch-from-config.ts to suppress all payloads that lack deliverDespiteSourceReplySuppression metadata.

The model intermittently skips calling the message tool — especially after long idle periods when the Anthropic prompt cache goes cold — even though the delivery hint ("Delivery: to send a message, use the message tool.") is present in every prompt.

Reproduction

  1. Configure a Telegram bot with default settings (queue mode: steer)
  2. Have an active group chat session with working message tool usage
  3. Wait 90+ minutes (long enough for the prompt cache to go cold)
  4. Send a message to the bot in the group chat
  5. The model generates a relevant response but may not call the message tool
  6. The response is silently dropped — no error, no delivery, no log indication

Evidence from trajectory data

Three consecutive broken turns in topic:2027 session, all with the same pattern:

Time (UTC)outputTokenstoolMetasdidSendassistantTextsmessagingToolSentTexts
20:16196[]false"Plan A from the playbook. 150g chicken + 150g roasted veg..."[]
20:1796[]false"Hey — did you see the lunch rec?..."[]
20:1956[]false"Lunch: 150g chicken + 150g roasted veg..."[]

Every working turn in the same session had toolMetas containing {"toolName":"message"}, didSend: true, and non-empty messagingToolSentTexts. A separate session (topic:1) broke at the same time with the same pattern.

Root cause

Two-part problem:

  1. Model behavior: claude-opus-4-7 intermittently generates direct text without calling the message tool, particularly after long idle gaps.

  2. Runtime suppression: In dispatch-from-config.ts (~line 1608):

    if (suppressDelivery && !shouldDeliverDespiteSourceReplySuppression(reply)) {
        continue; // payload silently skipped
    }

    When sourceReplyDeliveryMode is "message_tool_only", suppressDelivery is true. Only payloads marked with deliverDespiteSourceReplySuppression (set by markReplyPayloadForSourceSuppressionDelivery) survive. Plain assistant text payloads from buildEmbeddedRunPayloads never get this flag, so they are silently dropped.

Proposed fix

In agent-runner.ts, after the agent run completes: when sourceReplyDeliveryMode is "message_tool_only" and the model produced text payloads but no side-effect delivery occurred (no message tool, no block streaming), mark those payloads with deliverDespiteSourceReplySuppression so they bypass the dispatch suppression and the user still sees the response.

PR incoming.

Environment

  • OpenClaw v2026.5.12
  • Model: claude-opus-4-7 via Anthropic API
  • Channel: Telegram (group chat, queue mode: steer)
  • Block streaming enabled for Telegram

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…

Still need to ship something?

×6

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

Back to top recommendations

TRENDING