-
-
Notifications
You must be signed in to change notification settings - Fork 69.4k
[Bug] Duplicate Telegram messages when using ACP binding with shouldRouteToOriginating=true (v2026.3.24) #55603
Description
Bug type
Behavior bug (incorrect output/state without crash)
Beta release blocker
No
Summary
After upgrading to 2026.3.24, ACP binding to Telegram topic results in duplicate messages being sent.
Steps to reproduce
- Set up ACP binding with Kiro to Telegram group topic.
- Send a message to the topic.
- Kiro agent responds → same message appears twice.
Expected behavior
In 2026.3.23-2 the ACP binding works fine. Message only appears once.
Actual behavior
Root Cause
In dispatch-acp.runtime / src/auto-reply/reply/dispatch-acp-delivery.ts:
When shouldRouteToOriginating=true (Telegram → ACP binding), deliver() with kind="block" sends via routeReply() immediately AND accumulates into accumulatedBlockText. However, state.deliveredFinalReply is only set for kind="final".
In finalizeAcpTurnOutput, the guard !params.delivery.hasDeliveredFinalReply() is true (no "final" was delivered), so it sends accumulatedBlockText again as a second "final" message — duplicating the already-sent block content.
Exact Double-Send Path
- ACP agent streams response → block delivered via
routeReply()→ message sent to Telegram ✓ - Turn ends →
finalizeAcpTurnOutputruns →hasDeliveredFinalReply()=false→ sends same text again ✗
Likely Related Change
From 2026.3.24 changelog:
ACP/direct chats: always deliver a terminal ACP result when final TTS does not yield audio, even if block text already streamed earlier, and skip redundant empty-text final synthesis. (#53692)
This fix was for direct chats but may have caused regression for ACP bindings with shouldRouteToOriginating=true.
Suggested Fix
In finalizeAcpTurnOutput, add check for routedCounts.block:
// Current (buggy):
if (ttsMode !== "all" && hasAccumulatedBlockText && !finalMediaDelivered && !params.delivery.hasDeliveredFinalReply()) {
// Fixed:
if (ttsMode !== "all" && hasAccumulatedBlockText && !finalMediaDelivered
&& !params.delivery.hasDeliveredFinalReply()
&& params.delivery.getRoutedCounts().block === 0) {
Or alternatively, in deliver(), set deliveredFinalReply = true when a block is successfully routed via routeReply.
### OpenClaw version
2026.3.24
### Operating system
Ubuntu 24.04
### Install method
npm global
### Model
Minimax m2.5/Kiro
### Provider / routing chain
openclaw -> minimax
### Additional provider/model setup details
_No response_
### Logs, screenshots, and evidence
```shellImpact and severity
No response
Additional information
Bug report generated by Openclaw agent, model: Minimax m2.5, think/high