Version
OpenClaw 2026.5.12 (upgraded from 2026.5.7)
Symptom
Every Telegram reply lands as 2–4 duplicate sendMessage calls in a row. The draft-stream preview message edits in place as expected during the turn, then the final reply is delivered N times (where N = number of assistant blocks emitted during the turn).
Gateway log shows the duplicates clearly:
[telegram] sendMessage ok chat=<id> message=36645
[telegram] sendMessage ok chat=<id> message=36646
[telegram] sendMessage ok chat=<id> message=36647
[telegram] sendMessage ok chat=<id> message=36648
Four sends in 4 seconds for a single assistant reply.
Pre-5.12 (5.7): single sendMessage per reply.
Reproduction
- Configure Telegram with
channels.telegram.streaming.mode: "partial" and leave blockStreaming and agents.defaults.blockStreamingDefault unset/off.
- Send any message that produces an assistant turn with multiple text blocks (e.g. a checklist or multi-paragraph response).
- Observe N duplicate final messages on Telegram.
Config
Root cause
In agent-runner.runtime-*.js (line ~2381-2454), the final-payload dedupe branch only suppresses already-streamed blocks when blockStreamingEnabled === true OR directlySentBlockKeys.size > 0:
const shouldDropFinalPayloads = params.blockStreamingEnabled && Boolean(params.blockReplyPipeline?.didStream()) && !params.blockReplyPipeline?.isAborted();
// ...
const contentSuppressedPayloads = shouldDropFinalPayloads ? (() => {
// branch 1: blockStreaming on + did stream -> drop except unsent media
})() : params.blockStreamingEnabled ? (() => {
// branch 2: blockStreaming on, didnt stream -> use hasSentPayload
})() : params.directlySentBlockKeys?.size ? (() => {
// branch 3: directly sent media blocks -> subtract by key
})() : dedupedPayloads; // <-- branch 4: ALL payloads survive unfiltered
With streaming.mode: "partial" and blockStreamingDefault: "off" (default), blockStreamingEnabled = false. The draft-stream preview runs and edits a single message in place, but each text block also lands in dedupedPayloads. Branch 4 fires, all payloads survive, and sendFinalPayload in dispatch-*.js runs once per payload.
Likely related to PRs #79621/#79986 and the rich-reply content group of fixes in 5.12 that expanded what counts as deliverable content without widening the dedupe gate to cover non-blockStreaming partial-stream users.
Expected
A single final reply per assistant turn, matching pre-5.12 behavior.
Suggested fix
Extend the dedupe gate to cover preview-stream users, e.g.:
: (params.blockStreamingEnabled || params.previewStreamingActive) ? ... : ...
Workaround
agents.defaults.blockStreamingDefault: "on" (activates branch 2 dedup)
channels.telegram.streaming.mode: "off" (disables preview stream entirely)
Version
OpenClaw 2026.5.12 (upgraded from 2026.5.7)
Symptom
Every Telegram reply lands as 2–4 duplicate
sendMessagecalls in a row. The draft-stream preview message edits in place as expected during the turn, then the final reply is delivered N times (where N = number of assistant blocks emitted during the turn).Gateway log shows the duplicates clearly:
Four sends in 4 seconds for a single assistant reply.
Pre-5.12 (5.7): single sendMessage per reply.
Reproduction
channels.telegram.streaming.mode: "partial"and leaveblockStreamingandagents.defaults.blockStreamingDefaultunset/off.Config
Root cause
In
agent-runner.runtime-*.js(line ~2381-2454), the final-payload dedupe branch only suppresses already-streamed blocks whenblockStreamingEnabled === trueORdirectlySentBlockKeys.size > 0:With
streaming.mode: "partial"andblockStreamingDefault: "off"(default),blockStreamingEnabled = false. The draft-stream preview runs and edits a single message in place, but each text block also lands indedupedPayloads. Branch 4 fires, all payloads survive, andsendFinalPayloadindispatch-*.jsruns once per payload.Likely related to PRs #79621/#79986 and the rich-reply content group of fixes in 5.12 that expanded what counts as deliverable content without widening the dedupe gate to cover non-blockStreaming partial-stream users.
Expected
A single final reply per assistant turn, matching pre-5.12 behavior.
Suggested fix
Extend the dedupe gate to cover preview-stream users, e.g.:
Workaround
agents.defaults.blockStreamingDefault: "on"(activates branch 2 dedup)channels.telegram.streaming.mode: "off"(disables preview stream entirely)