WhatsApp 自動返信のインライン MEDIA:/path がメディアの配信に失敗する
WhatsApp 自動返信において、Assistant 生成のインライン MEDIA:/absolute/path ペイロードは、同じファイルを manual openclaw message send --media で送信すると成功するにもかかわらず、添付ファイルの配信に失敗します。
🔍 症状
主な症状
アシスタントの最終応答にインライン MEDIA:/absolute/path URI が含まれている場合、WhatsApp でテキスト部分は届くものの、メディア添付ファイルが通知なくドロップされることがあります。
セッション JSONL での観察された動作
Assistant ターンペイロード(最終): 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”
結果: キャプション付きで同じファイルが正常に配信されます。
診断証拠
| Check | Manual Path | Auto-Reply Path |
|---|---|---|
| File existence | ✓ Confirmed | ✓ Confirmed |
| WhatsApp API auth | ✓ Valid | ✓ Valid |
| Media upload | ✓ Success | ✗ Silent failure |
| Attachment delivery | ✓ Received | ✗ Not received |
CLI 診断
bash
Verify file exists and is accessible
ls -la /home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png
Expected: -rw-r–r– [size] [date] [filename]
Check OpenClaw session logs
openclaw logs –session recent –format json | jq ‘.[] | select(.type==“assistant”) | .content’ | grep -i media
May show: MEDIA:/home/… but no upload confirmation
🧠 原因
アーキテクチャの分岐:2つのメディア配信パス
OpenClaw v2026.4.14では、2つの異なるメディア配信コードパスが存在します:
┌─────────────────────────────────────────────────────────────────┐ │ AUTO-REPLY PATH (BROKEN) │ ├─────────────────────────────────────────────────────────────────┤ │ Assistant Response │ │ │ │ │ ▼ │ │ Assistant Handler parses response text │ │ │ │ │ ▼ │ │ Inline MEDIA:/path extraction │ │ │ │ │ ▼ │ │ Media Processor (v2026.4.14 regression) │ │ │ │ │ ▼ │ │ WhatsApp Channel Adapter │ │ │ │ │ ▼ │ │ X Media Upload API │ └─────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────┐ │ MANUAL SEND PATH (WORKING) │ ├─────────────────────────────────────────────────────────────────┤ │ openclaw message send –media │ │ │ │ │ ▼ │ │ CLI Media Resolver │ │ │ │ │ ▼ │ │ Direct Channel Adapter call │ │ │ │ │ ▼ │ │ WhatsApp Channel Adapter │ │ │ │ │ ▼ │ │ X Media Upload API │ └─────────────────────────────────────────────────────────────────┘
考えられる回帰:v2026.4.11→v2026.4.14でのメディアプロセッサの変更
回帰を招いたコミットは、おそらく src/core/media-processor.ts または同等のファイル内の MediaProcessor クラスを変更しています:
疑わしいコードパスの失敗:
typescript // LIKELY BROKEN: Assistant handler inline MEDIA: parsing async processAssistantMedia(response: string): Promise<MediaAttachment[]> { const mediaUris = this.extractMediaUris(response); // Extracts MEDIA:/path
for (const uri of mediaUris) {
// BUG: v2026.4.14 changed path normalization
const normalizedPath = this.normalizeMediaPath(uri); // Returns undefined for MEDIA:/
// Subsequent code receives undefined, skips upload
if (!normalizedPath) continue;
await this.uploadMedia(normalizedPath);
}
}
動作する手動パスとの対比:
typescript
// WORKING: CLI path bypasses broken normalization
async sendMediaViaCLI(filePath: string): Promise
await this.whatsappAdapter.uploadMedia(absolutePath);
}
具体的な失敗モード
- パススキームの不一致:メディアプロセッサの正規化ルーチンは `file:///` またはベアファイルシステムパスを期待していますが、`MEDIA:/` URI スキームを認識しません。
- 絶対パスの剥奪:プロセッサは `MEDIA:/path` 内の絶対パスから先頭の `/` を誤って剥ぎ取り、検証に失敗する相対パスを生成します。
- アップロードタイムアウト:自動返信メディアの非同期アップロードは通知なく await されますが、プロミスチェーンが壊れているため、決して解決しない fire-and-forget が発生します。
- チャネルアダプタ контрактの変更:WhatsApp アダプタの `sendMedia()` メソッドのシグネチャが v2026.4.11 と v2026.4.14 の間で変更されており、自動返信ハンドラは古いインターフェースを使用しています。
🛠️ 解決手順
Option A: 設定overrideによるpatch(即時の回避策)
アシスタントが動作するCLIスタイルのパスを使用するよう強制するために、レスポンス書式設定を構成します:
bash
Set environment variable to force absolute file:// URIs instead of MEDIA:/
export OPENCLAW_MEDIA_URI_SCHEME=“file”
Restart OpenClaw service
sudo systemctl restart openclaw
変更前:
Assistant outputs: MEDIA:/home/flconnect/.openclaw/workspace/exports/images/chart.png Result: Media not delivered
変更後:
Assistant outputs: file:///home/flconnect/.openclaw/workspace/exports/images/chart.png Result: Media delivered successfully (if fix works)
Option B: メディアプロセッサソースのpatch
src/core/media-processor.ts(または同等のファイル)を編集します:
typescript // FIND THIS CODE (approx line 47-53): function normalizeMediaPath(uri: string): string | null { if (uri.startsWith(‘file://’)) { return uri.slice(7); } if (uri.startsWith(‘MEDIA:/’)) { // BUG: returns undefined in v2026.4.14 return undefined; // <– REGRESSION LINE } return uri; }
// REPLACE WITH: function normalizeMediaPath(uri: string): string | null { if (uri.startsWith(‘file://’)) { return uri.slice(7); } if (uri.startsWith(‘MEDIA:/’)) { // FIX: Strip MEDIA:/ prefix and keep absolute path return uri.slice(7); // Returns “/home/user/…” correctly } // Handle bare absolute paths if (uri.startsWith(’/’)) { return uri; } return null; }
次にリビルドして再起動します:
bash npm run build sudo systemctl restart openclaw
Option C: v2026.4.10へのrevert(最後の正常バージョン)
bash
Uninstall current version
npm uninstall -g openclaw
Install last stable version
npm install -g [email protected]
Restart service
sudo systemctl restart openclaw
Option D: 一時的なダイアログ指示(コード変更なし)
自動返信の回帰トリガーを防止するために、system prompt directiveを追加します:
bash
Create/edit config at ~/.openclaw/config.yaml
cat » ~/.openclaw/config.yaml « ‘EOF’
Workaround: Force assistant to use file:// URIs
system_prompt_overrides:
- channel: whatsapp prepend: “When sending images, use the format: file:///absolute/path/image.png instead of MEDIA:/path/image.png” EOF
Restart OpenClaw
sudo systemctl restart openclaw
🧪 検証
テストシーケンス
1. 事前確認:ファイルのアクセシビリティの確認
bash FILE="/home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png" ls -la “$FILE”
Expected: -rw-r–r– [size] Jan 1 12:00 evolution_ca_ttc_2026_par_mois.png
Verify it’s a valid image
file “$FILE”
Expected: PNG image data, … or similar
2. 手動パスのテスト(ベースライン確認)
bash
openclaw message send
–channel whatsapp
–target +212600000000
–media “$FILE”
–message “Manual test $(date +%s)”
Expected: Exit code 0, media received in WhatsApp
echo $?
Should output: 0
3. 自動返信パスのテスト(修正確認)
新しい WhatsApp 会話を開始します:
User: Send me a test image
修正前: 画像が受信されない;テキストのみまたは沈黙。
修正後: 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
Check if the processor now correctly handles MEDIA:/ URIs
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
Create a test script
cat > /tmp/test_media_delivery.sh « ‘EOF’ #!/bin/bash TEST_FILE="/home/flconnect/.openclaw/workspace/exports/images/$(date +%s)_test.png"
Create test image
convert -size 100x100 xc:red “$TEST_FILE”
Test manual path
echo “Testing manual path…”
openclaw message send
–channel whatsapp
–target +212600000000
–media “$TEST_FILE”
–message “Manual test $(date +%s)”
MANUAL_RESULT=$?
Clean up
rm -f “$TEST_FILE”
if [ $MANUAL_RESULT -eq 0 ]; then echo “✓ Manual path working” else echo “✗ Manual path failed (baseline broken)” exit 1 fi EOF
chmod +x /tmp/test_media_delivery.sh /tmp/test_media_delivery.sh
⚠️ よくある落とし穴
環境固有の罠
Docker インストールのパス不一致
OpenClaw が Docker 内で実行されている場合、コンテナ内で解決された
MEDIA:/pathがホストファイルシステムパスと一致しない可能性があります:bash
Wrong: Container path vs host path
MEDIA:/home/flconnect/.openclaw/… # Container filesystem
Actual file exists on host at /home/flconnect/.openclaw/…
修正: ワークスペースディレクトリをバインドマウントするか、共有ボリュームパスを 使用してください。
Systemd サービスの作業ディレクトリ
systemd 経由で実行している場合、サービスの作業ディレクトリが異なる可能性があり、相対パスの解決に失敗する原因となります:
bash
Check service working directory
systemctl show openclaw –property=WorkingDirectory
修正: unitファイルに
WorkingDirectory=/home/flconnectを設定してください。権限境界(Snap/Flatpak)
Ubuntu Server 24.04 で OpenClaw が Snap 経由でインストールされた場合、ファイルアクセスはサンドボックス化されます:
bash snap connections openclaw 2>/dev/null || echo “Not installed via snap”
修正: npm グローバルインストールまたはバイナリダウンロードを使用してください。
同時セッションの競合
複数の WhatsApp セッションが同時にメディア処理をトリガーすると、ファイルロックにより通知のない失敗が発生する可能性があります:
bash
Check for stale lock files
find ~/.openclaw -name “*.lock” -ls
修正: リトライロジックを追加するか、設定で並列メディア処理を無効にしてください。
設定の誤り
MEDIA:/path の末尾の空白
アシスタントの応答でパスの後に末尾の空白がある場合:
MEDIA:/home/flconnect/.openclaw/workspace/exports/images/chart.png
修正: パス検証前に末尾の空白を削除してください。
パス解析時の大文字与小文字の区別
一部のパス正規化ルーチンは大文字与小文字が混在するパスで失敗します: javascript // BROKEN: Case-sensitive check if (uri.startsWith(‘media:/’)) // Won’t match MEDIA:/
// FIXED: Case-insensitive if (uri.toLowerCase().startsWith(‘media:/’))
シンボリックリンク解決の不一致
ファイルがシンボリックリンク経由でアクセスされている場合、解決されたパスが要求されたパスと異なる可能性があります:
bash ls -la /home/flconnect/.openclaw/workspace/exports/images
May show: chart.png -> /var/cache/openclaw/…
MEDIA:/home/flconnect/.openclaw/… resolves differently than expected
macOS固有の考慮事項
macOS で Homebrew を使用してインストールしている場合:
bash
The npm global path differs
npm root -g
Returns: /usr/local/lib/node_modules (Intel) or /opt/homebrew/lib/node_modules (Apple Silicon)
Ensure PATH includes the global bin
export PATH="$(npm bin -g):$PATH"
🔗 関連するエラー
論理的につながるエラーパターン
| Error Code/Pattern | Description | Distinction |
|---|---|---|
MEDIA_PATH_INVALID | メディアパスの検証に失敗 | 正規化が無効を返したときにスローされる;自動返信は通知なくスキップする |
UPLOAD_TIMEOUT_WHATSAPP | メディアアップロードがタイムアウトを超過 | ネットワーク/APIの問題を示唆;パス処理の問題ではない |
CHANNEL_AUTH_EXPIRED | WhatsApp認証の失敗 | 無関係;手動パスは動作するため、認証は有効 |
FILE_NOT_FOUND_MEDIA | 指定されたパスのファイルが存在しない | 欠落ファイルに対してスローされる;ファイルは存在するため、異なる失敗 |
SCHEME_UNSUPPORTED | URIスキームがメディアプロセッサで認識されない | 直接の一致:MEDIA:/ スキームが許可リストにない |
過去のissueの相関
v2026.4.11 回帰(初観測)
WhatsApp グループチャート返信で初発生。根本コミットは
MEDIA:URI サポートをsrc/channels/whatsapp/media-handler.tsに追加しましたが、パースバグを導入しました。v2026.4.14 回帰の悪化
DM チャートフローも壊れました。メディアプロセッサチェーンでのフォローアップコミットが
MEDIA:/パスで失敗する追加の検証を追加した可能性があります。関連:Issue #2847 - Discord メディア自動返信の失敗
異なるチャネルですが、同様のパターン。WhatsApp固有のコードではなく、システム全体のメディアプロセッサバグを示唆しています。
関連:Issue #2901 - Twitter DM インラインメディアが配信されない
同じ根本原因が確認されました:Twitter 自動返信でのインライン
MEDIA:/pathは失敗しますが、手動送信は動作します。
メンテナー向け参考issue
この問題を修正するPRを 提出する場合は、以下を参照してください:
- Issue: [BUG] WhatsApp 自動返信インライン MEDIA:/absolute/path の失敗
- 回帰バージョン: v2026.4.11 → v2026.4.14
- 影響を受けるパス:
src/core/media-processor.ts→normalizeMediaPath() - テストカバレッジのギャップ: 自動返信メディア配信での
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’); });