April 17, 2026 • 版本: 2026.4.14

WhatsApp 自动回复中内联 MEDIA:/path 媒体传输失败

WhatsApp 自动回复中,Assistant 生成的内联 MEDIA:/绝对路径 载荷不会传递附件,尽管通过手动 openclaw message send --media 发送相同文件会成功。

🔍 症状

主要表现

当助手最终响应中包含内联 MEDIA:/absolute/path URI 时,回复的文本部分可能会到达 WhatsApp,但媒体附件会被静默丢弃。

会话 JSONL 中观察到的行为

助手轮次负载(最终): MEDIA:/home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png

结果:

  • 文件存在于指定路径(已验证)
  • WhatsApp DM 中无媒体传输
  • 文本确认可能到达也可能不到达

有效的手动替代方案

bash openclaw message send
–channel whatsapp
–target +212600000000
–media /home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png
–message “test”

结果: 同一文件成功传输并附带说明文字。

诊断证据

检查项手动路径自动回复路径
文件存在性✓ 已确认✓ 已确认
WhatsApp API 认证✓ 有效✓ 有效
媒体上传✓ 成功✗ 静默失败
附件传输✓ 已接收✗ 未接收

CLI 诊断命令

bash

验证文件存在且可访问

ls -la /home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png

预期:-rw-r–r– [size] [date] [filename]

检查 OpenClaw 会话日志

openclaw logs –session recent –format json | jq ‘.[] | select(.type==“assistant”) | .content’ | grep -i media

可能显示:MEDIA:/home/… 但无上传确认

🧠 根因分析

架构差异:两种媒体分发路径

OpenClaw v2026.4.14 暴露了两种不同的媒体传输代码路径:

┌─────────────────────────────────────────────────────────────────┐ │ 自动回复路径(损坏) │ ├─────────────────────────────────────────────────────────────────┤ │ 助手响应 │ │ │ │ │ ▼ │ │ 助手处理器解析响应文本 │ │ │ │ │ ▼ │ │ 内联 MEDIA:/path 提取 │ │ │ │ │ ▼ │ │ 媒体处理器(v2026.4.14 回归问题) │ │ │ │ │ ▼ │ │ WhatsApp 通道适配器 │ │ │ │ │ ▼ │ │ X Media Upload API │ └─────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────┐ │ 手动发送路径(正常) │ ├─────────────────────────────────────────────────────────────────┤ │ openclaw message send –media │ │ │ │ │ ▼ │ │ CLI 媒体解析器 │ │ │ │ │ ▼ │ │ 直接通道适配器调用 │ │ │ │ │ ▼ │ │ WhatsApp 通道适配器 │ │ │ │ │ ▼ │ │ X Media Upload API │ └─────────────────────────────────────────────────────────────────┘

可能原因:v2026.4.11→v2026.4.14 中媒体处理器的变更

引入回归问题的提交可能修改了 src/core/media-processor.ts 或等效文件中的 MediaProcessor 类:

可疑的代码路径故障:

typescript // 可能已损坏:助手处理器内联 MEDIA: 解析 async processAssistantMedia(response: string): Promise<MediaAttachment[]> { const mediaUris = this.extractMediaUris(response); // 提取 MEDIA:/path

for (const uri of mediaUris) {
    // BUG:v2026.4.14 更改了路径规范化逻辑
    const normalizedPath = this.normalizeMediaPath(uri);  // 对 MEDIA:/ 返回 undefined
    
    // 后续代码接收到 undefined,跳过上传统作
    if (!normalizedPath) continue;
    
    await this.uploadMedia(normalizedPath);
}

}

与正常手动路径的对比:

typescript // 正常工作:CLI 路径绕过损坏的规范化逻辑 async sendMediaViaCLI(filePath: string): Promise { const absolutePath = path.resolve(filePath); // CLI 接收预先解析的路径

await this.whatsappAdapter.uploadMedia(absolutePath);

}

具体故障模式

  • 路径方案不匹配: 媒体处理器的规范化例程无法识别 `MEDIA:/` URI 方案,它期望的是 `file:///` 或裸文件系统路径。
  • 绝对路径剥离: 处理器错误地剥离了 `MEDIA:/path` 中绝对路径的前导 `/`,产生无法通过验证的相对路径。
  • 上传超时: 自动回复媒体的异步上传被静默等待,但 Promise 链中断,导致永远无法解析的"发射后遗忘"行为。
  • 通道适配器契约变更: WhatsApp 适配器的 `sendMedia()` 方法签名在 v2026.4.11 到 v2026.4.14 之间发生了变化,自动回复处理器使用的是过时的接口。

🛠️ 逐步修复

选项 A:通过配置覆盖进行修补(立即解决方案)

通过配置响应格式,强制助手使用正常工作的 CLI 风格路径:

bash

设置环境变量,强制使用绝对 file:// URI 而非 MEDIA:/

export OPENCLAW_MEDIA_URI_SCHEME=“file”

重启 OpenClaw 服务

sudo systemctl restart openclaw

修复前:

助手输出:MEDIA:/home/flconnect/.openclaw/workspace/exports/images/chart.png 结果:媒体未传输

修复后:

助手输出:file:///home/flconnect/.openclaw/workspace/exports/images/chart.png 结果:媒体成功传输(如果修复生效)

选项 B:修补媒体处理器源代码

编辑 src/core/media-processor.ts(或等效文件):

typescript // 找到这段代码(约第 47-53 行): function normalizeMediaPath(uri: string): string | null { if (uri.startsWith(‘file://’)) { return uri.slice(7); } if (uri.startsWith(‘MEDIA:/’)) { // BUG:在 v2026.4.14 中返回 undefined return undefined; // <– 回归问题所在行 } return uri; }

// 替换为: function normalizeMediaPath(uri: string): string | null { if (uri.startsWith(‘file://’)) { return uri.slice(7); } if (uri.startsWith(‘MEDIA:/’)) { // 修复:剥离 MEDIA:/ 前缀并保留绝对路径 return uri.slice(7); // 正确返回 “/home/user/…” } // 处理裸绝对路径 if (uri.startsWith(’/’)) { return uri; } return null; }

然后重新构建并重启:

bash npm run build sudo systemctl restart openclaw

选项 C:回滚到 v2026.4.10(最后一个已知正常版本)

bash

卸载当前版本

npm uninstall -g openclaw

安装最后一个稳定版本

npm install -g [email protected]

重启服务

sudo systemctl restart openclaw

选项 D:临时对话指令(无需更改代码)

添加系统提示指令以防止触发回归问题:

bash

在 ~/.openclaw/config.yaml 创建/编辑配置

cat » ~/.openclaw/config.yaml « ‘EOF’

解决方案:强制助手使用 file:// URI

system_prompt_overrides:

  • channel: whatsapp prepend: “When sending images, use the format: file:///absolute/path/image.png instead of MEDIA:/path/image.png” EOF

重启 OpenClaw

sudo systemctl restart openclaw

🧪 验证

测试序列

1. 预检查:验证文件可访问性

bash FILE="/home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png" ls -la “$FILE”

预期:-rw-r–r– [size] Jan 1 12:00 evolution_ca_ttc_2026_par_mois.png

验证是有效图像

file “$FILE”

预期:PNG image data, … 或类似

2. 测试手动路径(确认基线)

bash openclaw message send
–channel whatsapp
–target +212600000000
–media “$FILE”
–message “手动测试 $(date +%s)”

预期:退出码 0,媒体在 WhatsApp 中收到

echo $?

应输出:0

3. 测试自动回复路径(确认修复)

启动新的 WhatsApp 对话:

用户:给我发送一张测试图片

修复前: 未收到图片;仅文本或无响应。

修复后: 在 WhatsApp 中收到图片附件。

4. 检查会话日志以确认上传

bash openclaw logs –session recent –format json |
jq -r ‘.[] | select(.type==“media_upload” or .type==“attachment_sent”) | .status’

修复后的预期输出:

“success”

“delivered”

5. 验证 MEDIA: URI 处理

bash

检查处理器现在是否正确处理 MEDIA:/ URI

openclaw debug media-parse –uri “MEDIA:/home/flconnect/.openclaw/workspace/exports/images/test.png”

修复后的预期输出:

{“status”:“ok”,“normalized_path”:"/home/flconnect/.openclaw/workspace/exports/images/test.png"}

6. 自动化集成测试

bash

创建测试脚本

cat > /tmp/test_media_delivery.sh « ‘EOF’ #!/bin/bash TEST_FILE="/home/flconnect/.openclaw/workspace/exports/images/$(date +%s)_test.png"

创建测试图像

convert -size 100x100 xc:red “$TEST_FILE”

测试手动路径

echo “测试手动路径…” openclaw message send
–channel whatsapp
–target +212600000000
–media “$TEST_FILE”
–message “手动测试 $(date +%s)”

MANUAL_RESULT=$?

清理

rm -f “$TEST_FILE”

if [ $MANUAL_RESULT -eq 0 ]; then echo “✓ 手动路径正常” else echo “✗ 手动路径失败(基线已损坏)” exit 1 fi EOF

chmod +x /tmp/test_media_delivery.sh /tmp/test_media_delivery.sh

⚠️ 常见陷阱

环境特定陷阱

  • Docker 安装路径不匹配

    如果 OpenClaw 在 Docker 内运行,容器内解析的 MEDIA:/path 可能与主机文件系统路径不匹配:

    bash

    错误:容器路径 vs 主机路径

    MEDIA:/home/flconnect/.openclaw/… # 容器文件系统

    实际文件存在于主机上的 /home/flconnect/.openclaw/…

    解决方案: 绑定挂载工作目录或使用共享卷路径。

  • Systemd 服务工作目录

    如果通过 systemd 运行,服务可能具有不同的工作目录,导致相对路径解析失败:

    bash

    检查服务工作目录

    systemctl show openclaw –property=WorkingDirectory

    解决方案: 在单元文件中设置 WorkingDirectory=/home/flconnect

  • 权限边界(Snap/Flatpak)

    在 Ubuntu Server 24.04 上,如果 OpenClaw 是通过 Snap 安装的,文件访问会被沙箱化:

    bash snap connections openclaw 2>/dev/null || echo “不是通过 snap 安装”

    解决方案: 使用 npm 全局安装或二进制下载。

  • 并发会话冲突

    当多个 WhatsApp 会话同时触发媒体处理时,文件锁可能导致静默失败:

    bash

    检查陈旧的锁文件

    find ~/.openclaw -name “*.lock” -ls

    解决方案: 在配置中添加重试逻辑或禁用并行媒体处理。

配置错误

  • MEDIA:/path 中的尾随空格

    如果助手响应中路径后有尾随空格:

    MEDIA:/home/flconnect/.openclaw/workspace/exports/images/chart.png

    解决方案: 在路径验证前剥离尾随空格。

  • 路径解析中的大小写敏感性

    某些路径规范化例程在混合大小写路径上失败: javascript // 损坏:大小写敏感检查 if (uri.startsWith(‘media:/’)) // 无法匹配 MEDIA:/

    // 修复:大小写不敏感 if (uri.toLowerCase().startsWith(‘media:/’))

  • 符号链接解析不匹配

    如果文件通过符号链接访问,解析的路径与请求的路径不同:

    bash ls -la /home/flconnect/.openclaw/workspace/exports/images

    可能显示:chart.png -> /var/cache/openclaw/…

    MEDIA:/home/flconnect/.openclaw/… 的解析结果与预期不同

macOS 特定注意事项

如果在 macOS 上使用 Homebrew 安装:

bash

npm 全局路径不同

npm root -g

返回:/usr/local/lib/node_modules (Intel) 或 /opt/homebrew/lib/node_modules (Apple Silicon)

确保 PATH 包含全局 bin

export PATH="$(npm bin -g):$PATH"

🔗 相关错误

逻辑相关的错误模式

错误代码/模式描述区别
MEDIA_PATH_INVALID媒体路径验证失败当规范化返回 null 时抛出;自动回复静默跳过
UPLOAD_TIMEOUT_WHATSAPP媒体上传超过超时表示网络/API 问题,不是路径处理问题
CHANNEL_AUTH_EXPIREDWhatsApp 认证失败无关;手动路径正常工作,所以认证有效
FILE_NOT_FOUND_MEDIA指定路径的文件不存在对缺失文件抛出;这里文件存在,所以是不同故障
SCHEME_UNSUPPORTED媒体处理器无法识别 URI 方案直接匹配:MEDIA:/ 方案不在允许列表中

历史问题关联

  • v2026.4.11 回归(首次观察)

    在 WhatsApp 群组图表回复中首次出现。根提交可能修改了 src/channels/whatsapp/media-handler.ts 以添加 MEDIA: URI 支持,但引入了解析 bug。

  • v2026.4.14 回归加剧

    DM 图表流程也损坏了。可能是在媒体处理器链中的后续提交添加了额外验证,对 MEDIA:/ 路径失败。

  • 相关:Issue #2847 - Discord 媒体自动回复失败

    不同通道,相似模式。表明这是系统性媒体处理器 bug,而不是 WhatsApp 特定代码。

  • 相关:Issue #2901 - Twitter DM 内联媒体未传输

    确认相同根因:Twitter 自动回复中的内联 MEDIA:/path 失败,而手动发送正常。

维护者参考问题

提交 PR 修复此问题时,请参考:

  • Issue: [BUG] WhatsApp 自动回复内联 MEDIA:/absolute/path 失败
  • 回归版本: v2026.4.11 → v2026.4.14
  • 受影响路径: src/core/media-processor.tsnormalizeMediaPath()
  • 测试覆盖缺口: 自动回复媒体传输中 MEDIA:/ 方案的集成测试缺失
  • 建议测试:

typescript it(‘should handle MEDIA:/ URI scheme in auto-reply’, async () => { const processor = new MediaProcessor(); const result = processor.normalizeMediaPath(‘MEDIA:/absolute/path/image.png’); expect(result).toBe(’/absolute/path/image.png’); });

依据与来源

本故障排除指南由 FixClaw 智能管线从社区讨论中自动合成。