Skip to content

[Bug]: MEDIA: directive delivers voice/audio messages twice on all channels (4.15) #70085

Description

@altierac

Bug type

Regression (worked before, now fails)

Summary

Voice messages delivered via MEDIA:path + [[audio_as_voice]] are sent twice to Telegram, Discord, and WhatsApp. Confirmed on 2026.4.15, not fixed in 4.20.

Root Cause (confirmed via stack traces)

Two independent normalizeMediaPaths() instances fire for the same reply payload:

  1. onBlockReply (streaming handler) creates normalizer instance A with its own persistedMediaBySource cache
  2. buildReplyPayloads (final reply builder) creates normalizer instance B with a separate cache

Same MEDIA path → two UUID outbound files → two channel sends ~190ms apart.

Critically, onBlockReply fires for media content even with blockStreaming: false (the default).

Stack Traces

Send 1 (streaming handler):
dispatch.js:908 → bot:4888 → sendPayload → deliverReplies → sendVoice

Send 2 (buffered block dispatcher):
provider-dispatcher.js:4 → dispatch.js:979 (dispatchInboundMessage)
  → dispatch.js:39 (withReplyDispatcher) → dispatch.js:908
  → bot:4888 → sendPayload → deliverReplies → sendVoice

Steps to reproduce

  1. Configure Telegram or Discord channel
  2. Have the agent reply with MEDIA:/path/to/audio.mp3 + [[audio_as_voice]]
  3. Observe two identical voice messages delivered

Expected behavior

Single voice message delivery.

Actual behavior

Two voice messages delivered ~190ms apart from the same audio file. Both are audible. Different Telegram message IDs confirm two separate API calls.

Workaround

Use the message tool with action=send + filePath + asVoice=true then reply with NO_REPLY. This bypasses the reply-media normalization pipeline entirely.

Alternatively, using the built-in TTS system (messages.tts) also avoids this since it attaches audio directly to the delivery payload.

Related Issues

This appears to be the same root cause across multiple reports:

Environment

  • OpenClaw: 2026.4.15 (041266a)
  • OS: Ubuntu 24.04, Azure VM
  • Channels: Telegram + Discord (both affected)
  • blockStreamingDefault: off (default)
  • Node: v22.22.2

Suggested Fix Direction

The normalizeMediaPaths duplication could be resolved by either:

  1. Sharing a single normalizer cache between the streaming and final reply paths
  2. Deduplicating media payloads by source path before channel delivery
  3. Skipping the onBlockReply media path when blockStreaming is disabled

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions