Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
On OpenClaw 2026.4.15, one WhatsApp request that yields one media reply results in two media replies being sent to the same conversation.
Steps to reproduce
- Start OpenClaw 2026.4.15 with WhatsApp enabled and
channels.whatsapp.blockStreaming: false.
- Send one WhatsApp request that produces a single media response, for example a chart image.
- Observe that the agent sends two media replies for that one request to the same DM or group conversation.
- Confirm two outbound files are staged under
~/.openclaw/media/outbound/ within the same second for the single request.
- Confirm gateway logs contain two
Sent media reply lines for the same conversation within the same second.
Expected behavior
One request that produces one media response should result in exactly one outbound media file and exactly one WhatsApp media reply.
Actual behavior
One WhatsApp request that yields one media response produces two outbound media files and two WhatsApp media replies to the same conversation a few hundred milliseconds apart.
OpenClaw version
2026.4.15 (041266a)
Operating system
Ubuntu Server 24.04
Install method
npm global
Model
openai-codex/gpt-5.4
Provider / routing chain
openclaw -> openai
Additional provider/model setup details
The affected agent config sets `agents.defaults.model.primary` to `openai-codex/gpt-5.4` and uses the `openai-codex` auth profile in OAuth mode. No additional provider routing relevant to the reproduction was identified in the local agent config.
Logs, screenshots, and evidence
Additional evidence: a temporary instrumentation of `resolveOutboundAttachmentFromUrl` (logging `new Error().stack` on each call, subsequently reverted) captured two distinct call stacks for the same mediaUrl on a single reply.
Stack 1:
resolveOutboundAttachmentFromUrl (outbound-attachment-Dc2tDWj8.js:6:54)
persistLocalReplyMedia (reply-media-paths.runtime-B671n_FS.js:84:26)
normalizeMediaSource (reply-media-paths.runtime-B671n_FS.js:117:16)
Object.normalizeMediaPaths (reply-media-paths.runtime-B671n_FS.js:127:18)
Object.onBlockReply (agent-runner.runtime-CTlghBhJ.js:217:63)
Stack 2 (~190 ms later, same request, same mediaUrl):
resolveOutboundAttachmentFromUrl (outbound-attachment-Dc2tDWj8.js:6:54)
persistLocalReplyMedia (reply-media-paths.runtime-B671n_FS.js:84:26)
normalizeMediaSource (reply-media-paths.runtime-B671n_FS.js:117:16)
Object.normalizeMediaPaths (reply-media-paths.runtime-B671n_FS.js:127:18)
normalizeReplyPayloadMedia (agent-runner.runtime-CTlghBhJ.js:1631:10)
buildReplyPayloads (agent-runner.runtime-CTlghBhJ.js:1704:10)
async Promise.all (index 0)
Both stacks terminate at `resolveOutboundAttachmentFromUrl`, which calls `saveMediaBuffer(..., "outbound", ...)` and generates a fresh UUID per call. The two call sites create separate normalizer instances whose `persistedMediaBySource` caches are not shared; the identical input path therefore does not deduplicate across them, and each persists a separate outbound copy.
Stack 1 originates from `onBlockReply` despite `channels.whatsapp.blockStreaming: false` and `agents.defaults.blockStreamingDefault: "off"` in the active config.
Impact and severity
Affected users/systems/channels:
WhatsApp DM and WhatsApp group conversations on OpenClaw 2026.4.15.
Severity:
Medium. The agent responds, but every single-media reply is duplicated to the end user.
Frequency:
Observed repeatedly for the affected media-reply workflow in both DM and group tests.
Consequence:
Users receive duplicated chart/media messages for one request, which creates visible noise and reduces trust in the agent's output.
Additional information
Local agent-side checks did not identify a repo-level cause. The affected config still used tools.alsoAllow: ["message"], did not deny group:media or group:openclaw, and had channels.whatsapp.blockStreaming: false.
Additional debugging against the 2026.4.15 bundle suggests the duplicate is upstream in reply-media handling. For the affected reply, the final assistant output contained one MEDIA:<path> token once, but reply-media normalization appears to run through two paths for the same reply. Each path can stage the same media into outbound separately, producing two UUID files and two WhatsApp sends a few hundred milliseconds apart.
Bug type
Regression (worked before, now fails)
Beta release blocker
No
Summary
On OpenClaw 2026.4.15, one WhatsApp request that yields one media reply results in two media replies being sent to the same conversation.
Steps to reproduce
channels.whatsapp.blockStreaming: false.~/.openclaw/media/outbound/within the same second for the single request.Sent media replylines for the same conversation within the same second.Expected behavior
One request that produces one media response should result in exactly one outbound media file and exactly one WhatsApp media reply.
Actual behavior
One WhatsApp request that yields one media response produces two outbound media files and two WhatsApp media replies to the same conversation a few hundred milliseconds apart.
OpenClaw version
2026.4.15 (041266a)
Operating system
Ubuntu Server 24.04
Install method
npm global
Model
openai-codex/gpt-5.4
Provider / routing chain
openclaw -> openai
Additional provider/model setup details
The affected agent config sets `agents.defaults.model.primary` to `openai-codex/gpt-5.4` and uses the `openai-codex` auth profile in OAuth mode. No additional provider routing relevant to the reproduction was identified in the local agent config.
Logs, screenshots, and evidence
Impact and severity
Affected users/systems/channels:
WhatsApp DM and WhatsApp group conversations on OpenClaw 2026.4.15.
Severity:
Medium. The agent responds, but every single-media reply is duplicated to the end user.
Frequency:
Observed repeatedly for the affected media-reply workflow in both DM and group tests.
Consequence:
Users receive duplicated chart/media messages for one request, which creates visible noise and reduces trust in the agent's output.
Additional information
Local agent-side checks did not identify a repo-level cause. The affected config still used
tools.alsoAllow: ["message"], did not denygroup:mediaorgroup:openclaw, and hadchannels.whatsapp.blockStreaming: false.Additional debugging against the 2026.4.15 bundle suggests the duplicate is upstream in reply-media handling. For the affected reply, the final assistant output contained one
MEDIA:<path>token once, but reply-media normalization appears to run through two paths for the same reply. Each path can stage the same media intooutboundseparately, producing two UUID files and two WhatsApp sends a few hundred milliseconds apart.