[BUG] WhatsApp voice messages download as 0-byte files (Baileys downloadMediaMessage returns empty buffer)

Resolved 💬 2 comments Opened Jan 30, 2026 by nyaasuki Closed Jan 30, 2026

Description

WhatsApp voice messages (audio/ogg) are being saved as 0-byte files, while image files download correctly. The issue appears to be that Baileys downloadMediaMessage returns an empty buffer for audio messages without throwing an error.

Environment

  • OpenClaw version: Latest (npm)
  • Node.js: v22.22.0
  • Baileys version: 7.0.0-rc.9
  • OS: Linux (Debian)
  • WhatsApp channel: Web (Baileys)

Steps to Reproduce

  1. Configure WhatsApp channel in OpenClaw
  2. Send a voice message to the bot from WhatsApp
  3. Check the saved file in ~/.openclaw/media/inbound/

Expected Behavior

Voice message should be saved with actual audio data.

Actual Behavior

Voice message file is created but contains 0 bytes:

$ ls -la ~/.openclaw/media/inbound/
-rw------- 1 feng feng     0 Jan 30 20:36 8bbbe78e-02a9-4a4c-a071-4c50f0246023.ogg
-rw-r--r-- 1 feng feng 56141 Jan 28 22:46 6aa51e8d-0090-4764-b179-def8fa5d4303.jpg  # Images work fine

Analysis

Looking at the code in dist/web/inbound/media.js:

export async function downloadInboundMedia(msg, sock) {
    // ...
    try {
        const buffer = (await downloadMediaMessage(msg, "buffer", {}, {
            reuploadRequest: sock.updateMediaMessage,
            logger: sock.logger,
        }));
        return { buffer, mimetype };
    }
    catch (err) {
        logVerbose(`downloadMediaMessage failed: ${String(err)}`);
        return undefined;
    }
}

And in dist/media/store.js, saveMediaBuffer does not check for empty buffers:

export async function saveMediaBuffer(buffer, contentType, subdir = "inbound", maxBytes = MAX_BYTES, originalFilename) {
    if (buffer.byteLength > maxBytes) {
        throw new Error(`Media exceeds ${(maxBytes / (1024 * 1024)).toFixed(0)}MB limit`);
    }
    // ... writes buffer to file without checking if empty
}

The logs show the message is received with correct metadata but the file ends up empty:

{"body":"<media:audio>","mediaPath":"/home/feng/.openclaw/media/inbound/8bbbe78e-02a9-4a4c-a071-4c50f0246023.ogg","mediaType":"audio/ogg; codecs=opus"}

Suggested Fix

  1. Add empty buffer check in saveMediaBuffer:
export async function saveMediaBuffer(buffer, contentType, subdir = "inbound", maxBytes = MAX_BYTES, originalFilename) {
    if (!buffer || buffer.byteLength === 0) {
        throw new Error("Media buffer is empty");
    }
    // ... rest of function
}
  1. Or handle it in downloadInboundMedia:
const buffer = await downloadMediaMessage(msg, "buffer", {}, { ... });
if (!buffer || buffer.length === 0) {
    logVerbose("downloadMediaMessage returned empty buffer");
    return undefined;
}
return { buffer, mimetype };
  1. Investigate Baileys compatibility - This might be a known issue with Baileys 7.0.0-rc.9 and audio messages. Consider checking if there are specific handling requirements for audioMessage vs imageMessage.

Additional Context

  • Image downloads work perfectly (non-zero file sizes)
  • Only audio/voice messages are affected
  • No errors are logged during the download process
  • The file is created with correct extension (.ogg) but 0 bytes

---

Submitted by 猫猫 (Yachiyo Tsukimido) on behalf of @nyaasuki

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗