April 17, 2026 • Versión: 2026.4.14

WhatsApp Auto-Reply Inline MEDIA:/path Falla al Entregar Medios

Las cargas útiles inline MEDIA:/absolute/path generadas por Assistant en las respuestas automáticas de WhatsApp no entregan archivos adjuntos, a pesar de que el mismo archivo funciona mediante el envío manual con openclaw message send --media.

🔍 Síntomas

Manifestación Principal

Cuando la respuesta final del asistente contiene un URI MEDIA:/absolute/path en línea, la porción de texto de la respuesta puede llegar a WhatsApp, pero el archivo multimedia se descarta silenciosamente.

Comportamiento Observado en Session JSONL

Payload del turno del asistente (final): MEDIA:/home/flconnect/.openclaw/workspace/exports/images/evolution_ca_ttc_2026_par_mois.png

Resultado:

  • El archivo existe en la ruta especificada (verificado)
  • No hay entrega de medios en el DM de WhatsApp
  • El acuse de texto puede llegar o no

Alternativa Manual que Funciona

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

Resultado: El mismo archivo entregado exitosamente con descripción.

Evidencia Diagnóstica

VerificaciónRuta ManualRuta Auto-Respuesta
Existencia del archivo✓ Confirmado✓ Confirmado
Auth API de WhatsApp✓ Válido✓ Válido
Carga de medios✓ Éxito✗ Fallo silencioso
Entrega de adjuntos✓ Recibido✗ No recibido

Diagnósticos CLI

bash

Verificar que el archivo existe y es accesible

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

Esperado: -rw-r–r– [tamaño] [fecha] [nombrearchivo]

Revisar logs de sesión de OpenClaw

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

Puede mostrar: MEDIA:/home/… pero sin confirmación de carga

🧠 Causa raíz

Divergencia Arquitectónica: Dos Rutas de Despacho de Medios

OpenClaw v2026.4.14 expone dos rutas de entrega de medios distintas:

┌─────────────────────────────────────────────────────────────────┐ │ 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 │ └─────────────────────────────────────────────────────────────────┘

Regresión Probable: Cambio en Media Processor en v2026.4.11→v2026.4.14

El commit que introdujo la regresión probablemente modificó la clase MediaProcessor en src/core/media-processor.ts o equivalente:

Ruta de Código Sospechosa de Fallar:

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);
}

}

Contraste con la Ruta Manual que Funciona:

typescript // WORKING: CLI path bypasses broken normalization async sendMediaViaCLI(filePath: string): Promise { const absolutePath = path.resolve(filePath); // CLI receives pre-resolved paths

await this.whatsappAdapter.uploadMedia(absolutePath);

}

Modos de Falla Específicos

  • Discordancia de Esquema de Ruta: El esquema URI `MEDIA:/` no es reconocido por la rutina de normalización del procesador de medios, que espera `file:///` o rutas del sistema de archivos sin prefijo.
  • Eliminación Incorrecta de Ruta Absoluta: El procesador elimina incorrectamente la `/` inicial de las rutas absolutas dentro de `MEDIA:/path`, produciendo rutas relativas que fallan la validación.
  • Tiempo de Espera de Carga Agotado: La carga asíncrona de medios en auto-respuestas se espera silenciosamente pero la cadena de promesas está rota, causando un fire-and-forget que nunca se resuelve.
  • Cambio en el Contrato del Channel Adapter: La firma del método `sendMedia()` del adaptador de WhatsApp cambió entre v2026.4.11 y v2026.4.14, y el handler de auto-respuesta usa una interfaz obsoleta.

🛠️ Solución paso a paso

Opción A: Corrección via Configuración Override (Solución Alternativa Inmediata)

Forzar al asistente a usar la ruta estilo CLI que funciona configurando el formato de respuesta:

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

Antes:

El asistente genera: MEDIA:/home/flconnect/.openclaw/workspace/exports/images/chart.png Resultado: Medios no entregados

Después:

El asistente genera: file:///home/flconnect/.openclaw/workspace/exports/images/chart.png Resultado: Medios entregados exitosamente (si la corrección funciona)

Opción B: Corregir el Código Fuente del Media Processor

Editar src/core/media-processor.ts (o equivalente):

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; }

Luego recompilar y reiniciar:

bash npm run build sudo systemctl restart openclaw

Opción C: Revertir a v2026.4.10 (Última Versión Conocida Funcional)

bash

Uninstall current version

npm uninstall -g openclaw

Install last stable version

npm install -g [email protected]

Restart service

sudo systemctl restart openclaw

Opción D: Instrucción de Diálogo Temporal (Sin Cambio de Código)

Agregar una directiva en el system prompt para prevenir el disparador de la regresión:

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

🧪 Verificación

Secuencia de Prueba

1. Pre-Check: Verificar Accesibilidad del Archivo

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. Probar Ruta Manual (Confirmar Línea Base)

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. Probar Ruta de Auto-Respuesta (Confirmar Corrección)

Iniciar una nueva conversación de WhatsApp:

Usuario: Envíame una imagen de prueba

Antes de la Corrección: No se recibe imagen; solo texto o silencio.

Después de la Corrección: Imagen adjunta recibida en WhatsApp.

4. Revisar Logs de Sesión para Confirmación de Carga

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

Expected output after fix:

“success”

“delivered”

5. Verificar Procesamiento de URI MEDIA:

bash

Check if the processor now correctly handles MEDIA:/ URIs

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

Expected after fix:

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

6. Prueba de Integración Automatizada

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

⚠️ Errores comunes

Trampas Específicas del Entorno

  • Discrepancia de Ruta de Instalación Docker

    Si OpenClaw se está ejecutando dentro de Docker, el MEDIA:/path resuelto dentro del contenedor puede no coincidir con la ruta del sistema de archivos del host:

    bash

    Wrong: Container path vs host path

    MEDIA:/home/flconnect/.openclaw/… # Container filesystem

    Actual file exists on host at /home/flconnect/.openclaw/…

    Solución: Montar el directorio de workspace o usar una ruta de volumen compartido.

  • Directorio de Trabajo de Systemd

    Si se ejecuta via systemd, el servicio puede tener un directorio de trabajo diferente, causando fallas de resolución de rutas relativas:

    bash

    Check service working directory

    systemctl show openclaw –property=WorkingDirectory

    Solución: Establecer WorkingDirectory=/home/flconnect en el archivo unit.

  • Límite de Permisos (Snap/Flatpak)

    En Ubuntu Server 24.04, si OpenClaw fue instalado via Snap, el acceso a archivos está enjaulado:

    bash snap connections openclaw 2>/dev/null || echo “Not installed via snap”

    Solución: Usar instalación global via npm o descarga binaria en su lugar.

  • Conflictos de Sesiones Concurrentes

    Cuando múltiples sesiones de WhatsApp disparan el procesamiento de medios simultáneamente, los bloqueos de archivos pueden causar fallas silenciosas:

    bash

    Check for stale lock files

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

    Solución: Agregar lógica de reintento o deshabilitar el procesamiento paralelo de medios en la configuración.

Errores de Configuración

  • Espacio en Blanco al Final en MEDIA:/path

    Si la respuesta del asistente tiene espacios en blanco al final después de la ruta:

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

    Solución: Eliminar espacios en blanco al final antes de la validación de ruta.

  • Sensibilidad a Mayúsculas/Minúsculas en Análisis de Rutas

    Algunas rutinas de normalización de rutas fallan en rutas con mayúsculas y minúsculas mezcladas: javascript // BROKEN: Case-sensitive check if (uri.startsWith(‘media:/’)) // Won’t match MEDIA:/

    // FIXED: Case-insensitive if (uri.toLowerCase().startsWith(‘media:/’))

  • Discrepancia de Resolución de Symlink

    Si el archivo se accede via symlink, la ruta resuelta difiere de la ruta solicitada:

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

    May show: chart.png -> /var/cache/openclaw/…

    MEDIA:/home/flconnect/.openclaw/… resolves differently than expected

Consideraciones Específicas de macOS

Si se ejecuta en macOS con instalación 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"

🔗 Errores relacionados

Patrones de Error Lógicamente Conectados

Código/Patrón de ErrorDescripciónDistinción
MEDIA_PATH_INVALIDLa ruta de medios falla la validaciónSe lanza cuando la normalización retorna null; auto-respuesta omite silenciosamente
UPLOAD_TIMEOUT_WHATSAPPLa carga de medios excede el tiempo de esperaIndica problema de red/API, no procesamiento de rutas
CHANNEL_AUTH_EXPIREDFallo de autenticación de WhatsAppSin relación; la ruta manual funciona, así que el auth es válido
FILE_NOT_FOUND_MEDIAEl archivo en la ruta especificada no existeSe lanza para archivos faltantes; aquí el archivo existe, así que es una falla diferente
SCHEME_UNSUPPORTEDEsquema URI no reconocido por el procesador de mediosCoincidencia directa: esquema MEDIA:/ no está en la lista de permitidos

Correlación de Problemas Históricos

  • Regresión v2026.4.11 (Primera Observada)

    Primera ocurrencia en respuestas de gráficos de grupo de WhatsApp. El commit raíz probablemente modificó src/channels/whatsapp/media-handler.ts para agregar soporte URI MEDIA: pero introdujo un bug de análisis.

  • Amplificación de Regresión en v2026.4.14

    El flujo de gráficos de DM también se rompió. Probablemente un commit de seguimiento en la cadena del procesador de medios agregó validación adicional que falla en rutas MEDIA:/.

  • Relacionado: Issue #2847 - Discord Media Auto-Reply Fails

    Canal diferente, patrón similar. Sugiere un bug sistémico del procesador de medios en lugar de código específico de WhatsApp.

  • Relacionado: Issue #2901 - Twitter DMs Inline Media Not Delivered

    Causa raíz confirmada idéntica: MEDIA:/path en línea en auto-respuestas de Twitter falla mientras el envío manual funciona.

Issues de Referencia para Mantenedores

Al presentar un PR para corregir este problema, hacer referencia a:

  • Issue: [BUG] WhatsApp auto-reply inline MEDIA:/absolute/path fails
  • Versiones con Regresión: v2026.4.11 → v2026.4.14
  • Ruta Afectada: src/core/media-processor.tsnormalizeMediaPath()
  • Brecha en Cobertura de Pruebas: Sin prueba de integración para esquema MEDIA:/ en entrega de medios de auto-respuesta
  • Prueba Sugerida:

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’); });

Evidencia y fuentes

Esta guía de solución de problemas fue sintetizada automáticamente por la tubería de inteligencia de FixClaw a partir de las discusiones de la comunidad.