openclaw - 💡(How to fix) Fix WhatsApp outbound media upload can crash gateway with ENOENT on Baileys *-enc temp files [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#72895Fetched 2026-04-28 06:30:41
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Participants
Timeline (top)
cross-referenced ×1

WhatsApp outbound media sends can fail with an uncaught ENOENT while Baileys is opening its temporary encrypted media file (image...-enc / document...-enc). In my case this repeatedly crashed/restarted the OpenClaw Gateway.

Text send and inbound WhatsApp media receive were working. The failure was specific to bot -> WhatsApp outbound media upload.

This looks related to the WhatsApp/Baileys media upload path and distinct from generic “No active WhatsApp Web listener” startup/recovery issues. I did see listener errors during recovery after crashes, but the root crash was the temp encrypted media file read.

Error Message

Gateway logs showed repeated media send attempts followed by uncaught exceptions:

Root Cause

WhatsApp outbound media sends can fail with an uncaught ENOENT while Baileys is opening its temporary encrypted media file (image...-enc / document...-enc). In my case this repeatedly crashed/restarted the OpenClaw Gateway.

Text send and inbound WhatsApp media receive were working. The failure was specific to bot -> WhatsApp outbound media upload.

This looks related to the WhatsApp/Baileys media upload path and distinct from generic “No active WhatsApp Web listener” startup/recovery issues. I did see listener errors during recovery after crashes, but the root crash was the temp encrypted media file read.

Fix Action

Fix / Workaround

  • OpenClaw: 2026.4.24 (cbcfdf6)
  • Latest npm at time of debugging: 2026.4.25
  • OS: macOS 26.4.1 arm64
  • Node: v24.15.0
  • Gateway service: macOS LaunchAgent
  • WhatsApp channel: Web/Baileys, linked and able to receive inbound messages
  • Proxy env present, but the old Node/fetch dispatcher issue was already mitigated with OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT=1

Both contained Baileys lib/Utils/messages-media.js. One copy had been patched earlier, but the other still used createReadStream(filePath) for the encrypted temp file upload path, so the Gateway could still crash depending on which runtime copy was loaded.

const stream = createReadStream(filePath);
const response = await fetch(url, {
  dispatcher: fetchAgent,
  method: 'POST',
  body: stream,
  headers,
  duplex: 'half',
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
});

Code Example

python3 - <<'PY'
import base64
png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="
open('/tmp/tiny.png', 'wb').write(base64.b64decode(png))
PY

openclaw message send \
  --channel whatsapp \
  --target "+<redacted>" \
  --message "tiny PNG media upload test" \
  --media /tmp/tiny.png \
  --json

---

[whatsapp] Sending message -> sha256:<redacted> (media)
[openclaw] Uncaught exception: Error: ENOENT: no such file or directory, open '/var/folders/.../T/document...-enc'
[openclaw] wrote stability bundle: .../logs/stability/...-uncaught_exception.json

---

[openclaw] Uncaught exception: Error: ENOENT: no such file or directory, open '/var/folders/.../T/image...-enc'

---

[whatsapp] Failed sending web media to +<redacted>: Media upload failed on all hosts
[whatsapp] Media skipped; sent text-only to +<redacted>

---

~/.openclaw/plugin-runtime-deps/openclaw-2026.4.24-.../
~/.openclaw/plugin-runtime-deps/openclaw-unknown-.../

---

const stream = createReadStream(filePath);
const response = await fetch(url, {
  dispatcher: fetchAgent,
  method: 'POST',
  body: stream,
  headers,
  duplex: 'half',
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
});

---

const body = await fs.readFile(filePath);
const fetchOptions = {
  method: 'POST',
  body,
  headers,
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
};

if (!process.env.OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT && fetchAgent) {
  fetchOptions.dispatcher = fetchAgent;
}

const response = await fetch(url, fetchOptions);

---

const DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS = 60000;
function resolveWhatsAppMediaUploadTimeoutMs() {
  const raw = process.env.OPENCLAW_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
  if (!raw) return DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
  const value = Number.parseInt(raw, 10);
  return Number.isFinite(value) && value > 0 ? value : DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
}

---

LocalMediaAccessError: Host-local media sends only allow buffer-verified images, audio, video, PDF, and Office documents (got text/plain).
RAW_BUFFERClick to expand / collapse

Summary

WhatsApp outbound media sends can fail with an uncaught ENOENT while Baileys is opening its temporary encrypted media file (image...-enc / document...-enc). In my case this repeatedly crashed/restarted the OpenClaw Gateway.

Text send and inbound WhatsApp media receive were working. The failure was specific to bot -> WhatsApp outbound media upload.

This looks related to the WhatsApp/Baileys media upload path and distinct from generic “No active WhatsApp Web listener” startup/recovery issues. I did see listener errors during recovery after crashes, but the root crash was the temp encrypted media file read.

Environment

  • OpenClaw: 2026.4.24 (cbcfdf6)
  • Latest npm at time of debugging: 2026.4.25
  • OS: macOS 26.4.1 arm64
  • Node: v24.15.0
  • Gateway service: macOS LaunchAgent
  • WhatsApp channel: Web/Baileys, linked and able to receive inbound messages
  • Proxy env present, but the old Node/fetch dispatcher issue was already mitigated with OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT=1

Repro shape

python3 - <<'PY'
import base64
png = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+/p9sAAAAASUVORK5CYII="
open('/tmp/tiny.png', 'wb').write(base64.b64decode(png))
PY

openclaw message send \
  --channel whatsapp \
  --target "+<redacted>" \
  --message "tiny PNG media upload test" \
  --media /tmp/tiny.png \
  --json

I also reproduced with generated images and PDF/document sends.

Observed behavior

Gateway logs showed repeated media send attempts followed by uncaught exceptions:

[whatsapp] Sending message -> sha256:<redacted> (media)
[openclaw] Uncaught exception: Error: ENOENT: no such file or directory, open '/var/folders/.../T/document...-enc'
[openclaw] wrote stability bundle: .../logs/stability/...-uncaught_exception.json

Later image sends showed the same class of error:

[openclaw] Uncaught exception: Error: ENOENT: no such file or directory, open '/var/folders/.../T/image...-enc'

I also saw this once during the same failure window:

[whatsapp] Failed sending web media to +<redacted>: Media upload failed on all hosts
[whatsapp] Media skipped; sent text-only to +<redacted>

After the crash, delivery recovery sometimes logged No active WhatsApp Web listener, but that appeared to be a recovery/startup symptom after Gateway restart, not the original media upload failure.

Local investigation

The active runtime had two plugin runtime dependency directories:

~/.openclaw/plugin-runtime-deps/openclaw-2026.4.24-.../
~/.openclaw/plugin-runtime-deps/openclaw-unknown-.../

Both contained Baileys lib/Utils/messages-media.js. One copy had been patched earlier, but the other still used createReadStream(filePath) for the encrypted temp file upload path, so the Gateway could still crash depending on which runtime copy was loaded.

The relevant Baileys upload path was getWAUploadToServer(...), which did roughly:

const stream = createReadStream(filePath);
const response = await fetch(url, {
  dispatcher: fetchAgent,
  method: 'POST',
  body: stream,
  headers,
  duplex: 'half',
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
});

My hypothesis is that the encrypted temp file exists when the upload function is called, but createReadStream(filePath) opens/reads asynchronously. If cleanup or another lifecycle path removes the *-enc file before the stream actually opens, the stream emits ENOENT and it escapes as an uncaught exception.

Local workaround that fixed it

I changed both active Baileys runtime copies so the WhatsApp upload path snapshots the encrypted temp file before calling fetch, and keeps the existing dispatcher bypass env behavior:

const body = await fs.readFile(filePath);
const fetchOptions = {
  method: 'POST',
  body,
  headers,
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
};

if (!process.env.OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT && fetchAgent) {
  fetchOptions.dispatcher = fetchAgent;
}

const response = await fetch(url, fetchOptions);

I also changed the OpenClaw WhatsApp media send timeout from a hard-coded mediaUploadTimeoutMs: 10000 to a configurable default of 60s:

const DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS = 60000;
function resolveWhatsAppMediaUploadTimeoutMs() {
  const raw = process.env.OPENCLAW_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
  if (!raw) return DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
  const value = Number.parseInt(raw, 10);
  return Number.isFinite(value) && value > 0 ? value : DEFAULT_WHATSAPP_MEDIA_UPLOAD_TIMEOUT_MS;
}

Result after workaround

After patching both runtime copies and restarting Gateway:

  • tiny PNG outbound send succeeded
  • small PDF outbound send succeeded
  • Gateway stayed up
  • no new image...-enc / document...-enc ENOENT appeared in the recent logs

The text/plain test still failed, but that was a separate local media policy rejection:

LocalMediaAccessError: Host-local media sends only allow buffer-verified images, audio, video, PDF, and Office documents (got text/plain).

Suggested fix

At the OpenClaw layer, it would help to:

  1. Ensure WhatsApp outbound media upload cannot crash the whole Gateway if Baileys temp-file reads fail.
  2. Patch or wrap the Baileys upload path to avoid asynchronous createReadStream(filePath) races against temp-file cleanup, or otherwise catch stream ENOENT reliably.
  3. Keep the OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT=1 style dispatcher bypass for Node global fetch / vendored undici agent mismatch.
  4. Make media upload timeout configurable rather than hard-coded at 10s.
  5. Consider clarifying/synchronizing how multiple plugin-runtime-deps/openclaw-* runtime copies are selected, since patching only one copy left the Gateway still using the unpatched behavior.

I can provide more sanitized logs if useful.

extent analysis

TL;DR

The most likely fix is to patch the Baileys upload path to avoid asynchronous createReadStream(filePath) races against temp-file cleanup.

Guidance

  • Verify that the issue is indeed caused by the asynchronous createReadStream(filePath) call by checking the Gateway logs for ENOENT errors and the presence of multiple plugin-runtime-deps/openclaw-* runtime copies.
  • Patch the Baileys upload path to snapshot the encrypted temp file before calling fetch, as shown in the local workaround.
  • Consider implementing a try-catch block to catch stream ENOENT errors and prevent them from crashing the Gateway.
  • Make the media upload timeout configurable, rather than hard-coded, to allow for more flexibility in handling upload failures.

Example

const body = await fs.readFile(filePath);
const fetchOptions = {
  method: 'POST',
  body,
  headers,
  signal: timeoutMs ? AbortSignal.timeout(timeoutMs) : undefined,
};

if (!process.env.OPENCLAW_WHATSAPP_MEDIA_UPLOAD_NO_FETCH_AGENT && fetchAgent) {
  fetchOptions.dispatcher = fetchAgent;
}

const response = await fetch(url, fetchOptions);

Notes

The issue may be specific to the Baileys library and the OpenClaw Gateway, and may not be applicable to other environments or libraries. Additionally, the presence of multiple plugin-runtime-deps/openclaw-* runtime copies may cause issues if not properly synchronized.

Recommendation

Apply the workaround by patching the Baileys upload path to avoid asynchronous createReadStream(filePath) races against temp-file cleanup, and make the media upload timeout configurable. This should prevent the Gateway from crashing due to ENOENT errors and allow for more flexible handling of upload failures.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix WhatsApp outbound media upload can crash gateway with ENOENT on Baileys *-enc temp files [1 participants]