#8076: fix(web): handle data URLs in loadWebMedia to prevent ENAMETOOLONG
channel: whatsapp-web
stale
Cluster:
Media Handling Improvements
## Problem
When a data URL (e.g., `data:image/png;base64,iVBORw0KGgo...`) was passed to `loadWebMedia()`, it fell through to the local file path handling because the function only explicitly handled `file://` and `http(s)://` URLs.
This caused the entire base64 string (often 5,000+ characters) to be used as a filename, resulting in `ENAMETOOLONG` errors (filesystem filename limit is typically ~255 bytes).
### Trigger Flow
1. `whatsapp_login` tool generates QR code → returns markdown with data URL
2. Agent tries to send/resend via message tool
3. `handleSendAction` extracts data URL as `mediaUrl`
4. `executeSendAction` → `deliverOutboundPayloads` → `handler.sendMedia`
5. `loadWebMedia(mediaUrl)` doesn't recognize data URL
6. Falls through to `fs.readFile("data:image/png;base64,...")` → **CRASH**
### Impact
- 10-minute request timeout
- Auth profile enters cooldown state
- Blocks all subsequent requests until manually cleared
- Requires editing `~/.openclaw/agents/main/agent/auth-profiles.json`
## Solution
Add explicit data URL detection before the local file path handling. The fix parses the data URL to extract the MIME type and base64 payload, converting directly to a Buffer without filesystem access.
## Related Issues
Fixes #4838
Related: #6640 (QR rendering issues), #4956 (connection timeout)
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates `loadWebMediaInternal` (`src/web/media.ts`) to explicitly recognize `data:` URLs and decode their base64 payload directly into a `Buffer`, preventing accidental fallback to `fs.readFile()` with multi‑KB “filenames” that trigger `ENAMETOOLONG`. The change sits alongside existing handling for `http(s)://` remote fetches and `file://` URLs / local paths, and returns the decoded media through the existing `clampAndFinalize` pipeline (including image optimization/clamping).
<h3>Confidence Score: 4/5</h3>
- This PR is likely safe to merge and addresses the reported crash, with a couple of edge-case/logging considerations around data URL parsing.
- Change is localized and routed through existing clamping/optimization logic. Main remaining concerns are (1) only base64 `data:` URLs are supported (valid non-base64 forms will throw) and (2) error text currently includes a prefix of the URL, which can leak embedded content into logs if user-controlled.
- src/web/media.ts
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#9817: fix(media): resolve relative paths before reading local files (#8759)
by lailoo · 2026-02-05
79.7%
#20913: fix: intercept Discord embed images to enforce mediaMaxMb
by MumuTW · 2026-02-19
77.1%
#22088: fix(web): sanitize media errors to prevent PII leak
by ashiabbott · 2026-02-20
76.3%
#9598: fix(agents): check base64 string length against 5MB API limit
by BlockBB · 2026-02-05
76.1%
#14794: fix: parse inline MEDIA: tokens in agent replies
by explainanalyze · 2026-02-12
75.3%
#9606: fix: pass fileName to WhatsApp document messages
by AytuncYildizli · 2026-02-05
75.2%
#16938: fix(media): reject unsupported URL schemes with clear error message
by zerone0x · 2026-02-15
75.1%
#20294: fix(message): thread mediaLocalRoots through channel plugin dispatch
by odrobnik · 2026-02-18
75.0%
#11443: LINE: fix buffer guards in detectContentType + add tests
by MdRahmatUllah · 2026-02-07
75.0%
#8284: Fix: Webchat images now persist after sending
by vishaltandale00 · 2026-02-03
74.9%