Sharing a fix for others hitting silent image download failures in BlueBubbles (iMessage) and Slack channels. Took a full day of debugging to find — posting here so others don't have to.
Symptom
Agent receives messages with image attachments but never saves them to ~/.openclaw/media/inbound/. No visible error. Agent replies saying it can't see the image. This affects both BlueBubbles and Slack on macOS, OpenClaw v2026.4.5.
Root Cause
The fetchRemoteMedia helper creates an undici dispatcher via the SSRF guard and passes it as part of init to the fetchImpl callback. When that reaches Node's native fetch(), it throws:
fetch failed | invalid onRequestStart method
This is silently swallowed by the surrounding try/catch. Nothing is logged at default log levels.
Fix
Replace fetchRemoteMedia + SSRF guard with plain fetch() + AbortController in two places:
1. BlueBubbles (reactions-*.js — downloadBlueBubblesAttachment)
const controller = new AbortController();
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 30000);
try {
const response = await fetch(url, { method: 'GET', signal: controller.signal });
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const buf = await response.arrayBuffer();
return { buffer: new Uint8Array(buf), contentType: response.headers.get('content-type') ?? attachment.mimeType };
} finally { clearTimeout(timer); }
Safe because dangerouslyAllowPrivateNetwork: true is already in config for local network access.
2. Slack (actions-*.js — resolveSlackMedia)
Same pattern but add the Bearer token header:
const response = await fetch(url, {
method: 'GET',
headers: { Authorization: `Bearer ${params.token}` },
redirect: 'follow',
signal: controller.signal
});
3. Also required for BlueBubbles (channel.runtime-*.js)
Add allowPrivateNetwork to the downloadBlueBubblesAttachment call opts — it was being silently dropped:
const downloaded = await downloadBlueBubblesAttachment(attachment, {
cfg: config,
accountId: account.accountId,
maxBytes,
allowPrivateNetwork: isPrivateNetworkOptInEnabled(account.config) // ← add this
});
Verified
Both iMessage (BlueBubbles, Private API disabled) and Slack image attachments now download correctly and are described by the agent.
Related
Original bug report with full diagnosis trail: #62248
Sharing a fix for others hitting silent image download failures in BlueBubbles (iMessage) and Slack channels. Took a full day of debugging to find — posting here so others don't have to.
Symptom
Agent receives messages with image attachments but never saves them to
~/.openclaw/media/inbound/. No visible error. Agent replies saying it can't see the image. This affects both BlueBubbles and Slack on macOS, OpenClaw v2026.4.5.Root Cause
The
fetchRemoteMediahelper creates an undicidispatchervia the SSRF guard and passes it as part ofinitto thefetchImplcallback. When that reaches Node's nativefetch(), it throws:This is silently swallowed by the surrounding try/catch. Nothing is logged at default log levels.
Fix
Replace
fetchRemoteMedia+ SSRF guard with plainfetch()+AbortControllerin two places:1. BlueBubbles (
reactions-*.js—downloadBlueBubblesAttachment)Safe because
dangerouslyAllowPrivateNetwork: trueis already in config for local network access.2. Slack (
actions-*.js—resolveSlackMedia)Same pattern but add the Bearer token header:
3. Also required for BlueBubbles (
channel.runtime-*.js)Add
allowPrivateNetworkto thedownloadBlueBubblesAttachmentcall opts — it was being silently dropped:Verified
Both iMessage (BlueBubbles, Private API disabled) and Slack image attachments now download correctly and are described by the agent.
Related
Original bug report with full diagnosis trail: #62248