← NEWS DESK
release impact

OpenClaw Closes a Two-Owner Retry Bug That Duplicated Telegram Sends

When the message tool failed with proven-not-sent evidence, both the durable outbound queue and the model held the same retry, so recipients got two copies seconds apart. Merged fixes make the queue the single retry owner, including remote Gateway deployments.

Independent reporting and tested guidance for OpenClaw operators · Editorial standards

If you run OpenClaw against Telegram and your recipients have ever received the same answer twice, roughly five to fifteen seconds apart, merged fixes #124310 and its remote-Gateway follow-up #128202 explain why — and remove the failure mode. Both are on main as of August 23, 2026. Update to a build containing them and audit whether any of your automations were built around the old duplicate behavior.

The bug: two owners, one retry

The failure needed three ingredients, and standard deployments supply all three:

  1. A model-authored send through the message tool fails with proven-not-sent evidence — a pre-connect ECONNREFUSED or ETIMEDOUT on connect, or a platform-level dispatch rejection.
  2. The durable write-ahead delivery row was marked with failDeliveryBeforePlatformSend, which cleared platformSendAttemptId, platformSendStartedAt, and recoveryState. That left the row fully replay-eligible.
  3. The same error was also thrown back to the caller. For an agent-authored send, that means the message tool returned the failure to the model, and the model did what models do with errors: it retried.

The recipient then got the model’s retry plus the reconnect/poll drain replaying the very row the model had been told had failed. On Telegram the drain fires on the next successful poll, which is where the characteristic 5–15 second gap between copies came from. Issue #124279 tracks the report.

What #124310 changed

PR #124310 assigns retry ownership at the two producers of model-authored sends and dead-letters caller-owned proven-not-sent rows in the durable queue. After it, the model’s resend is the only retry; the queue stops holding a second live copy of the same delivery.

One boundary mattered enough to get its own fix: this works only when the Gateway can see that the caller is an agent run (runtimeAgentId).

What #128202 changed for remote Gateways

In remote Gateway mode (gateway.mode: "remote", or a gatewayUrl/gatewayToken override), the agent runtime deliberately mints no runtime identity. The Gateway therefore could not classify the caller as an agent run, kept the row replay-eligible and returned the error to the model — recreating the two-owner duplicate even after #124310.

The follow-up makes the queue the single retry owner in that topology too:

  • deliver-queue-execute.ts marks the thrown error with recoveryOwnedRetry whenever a proven-not-sent failure keeps the row.
  • gateway/server-methods/send.ts maps that marker into what the message.action response tells the model — so the model is informed the durable queue owns recovery and does not need to resend.

Operator actions

  • Update to a build containing #124310 and #128202 before trusting delivery counts in incident reviews; older builds double-send under transient network faults.
  • If you run a remote Gateway, treat #128202 as required, not optional — the first fix alone does not cover your topology.
  • Reread past “duplicate message” incidents: if timestamps cluster a few seconds apart around a connectivity blip, you now have a root cause. No re-sends are needed on upgrade; there is no data migration, just behavior.
  • Check automation assumptions: anything that deduplicated by content-hash or suppressed “repeat” answers may have been compensating for this bug. Loosen those workarounds deliberately, not silently.

Interpretation note: chronology and mechanism above come from the merged PR descriptions and linked issue. The 5–15 second figure is the PR’s own Telegram-drain estimate, not our measurement. Severity judgments are ours: we rate this an availability/trust defect worth prioritizing for channel-facing deployments, but it is not a security vulnerability and carries no CVE or advisory.

THE RECEIPTS

Claims should survive the click.

Primary links used for this article are listed openly. If the evidence changes, the verification date changes with it.
  1. 01fix(outbound): prevent duplicate sends from proven-not-sent message-tool failures — PR #124310
  2. 02Issue #124279: duplicate sends from proven-not-sent failures (fixed by #124310)
  3. 03fix(outbound): prevent remote gateway duplicate sends — PR #128202

THE OPERATOR BRIEF

One useful email when the signal earns it.

Release impact, security changes and repository intelligence. No daily sludge.