April 18, 2026 • Versión: 26.4.12 - 26.4.14

Active Memory Timeout: Blocking Recall Pass Excede el Tiempo de Espera Configurado

Active Memory consistentemente excede el tiempo de espera antes de devolver summaries recuperadas a través de múltiples models y providers, con el timeout disparándose en ~8084ms a pesar de una configuración de 8000ms.

🔍 Síntomas

Active Memory no logra completar su paso de recuperación bloqueante dentro del ventana de tiempo de espera configurada. La siguiente salida de diagnóstico aparece consistentemente:


🧩 Active Memory: timeout 8084ms message 0 chars
🔎 Active Memory Debug: none retrieved

Los logs del gateway confirman el comportamiento de timeout:


active-memory ... done status=timeout elapsedMs=8092 summaryChars=0
embedded_run_failover_decision ... failoverReason=timeout profileFailureReason=timeout

Manifestaciones Diagnósticas

  • Umbral de timeout: El timeout se activa en ~8084-8092ms (vs. los 8000ms configurados), lo que indica que la verificación del timeout ocurre después de que comienza la llamada bloqueante
  • Respuesta de cero bytes: summaryChars=0 confirma que no se generó ningún resumen antes del timeout
  • Agnóstico al modelo: El problema se reproduce en todos los modelos probados:
    • openai-codex/gpt-5.4
    • ollama/glm-5.1:cloud
    • ollama/llama3.1:8b
    • ollama/gemma4:e4b
  • Agnóstico al backend: Tanto los entornos de ejecución inactivos como los ocupados/en cola presentan comportamiento idéntico
  • Cadena de proveedores: Afecta la configuración de enrutamiento openclaw → ollama

Contexto del Entorno

ComponenteValor
Versión de OpenClaw2026.4.12 / 26.4.14
Sistema OperativomacOS
Método de Instalaciónnpm global
Backend de Memoriabuiltin/default (memory-core)
Modelo de Embeddingqwen3-embedding (Ollama)
Contexto de ChatDiscord DM (directo)

🧠 Causa raíz

Causa Raíz Principal: Recuperación Síncrona de Embeddings Bloqueante

El timeout ocurre porque el paso de recuperación bloqueante de Active Memory realiza búsquedas de embeddings síncronas contra el backend de memoria antes de invocar el LLM para la resumación. Cuando la fase de recuperación de embeddings excede el timeout configurado, la llamada al LLM nunca se ejecuta.

Análisis de la Secuencia de Fallas


┌─────────────────────────────────────────────────────────────┐
│ Active Memory Blocking Recall Pass                          │
├─────────────────────────────────────────────────────────────┤
│ 1. Memory Query (synchronous)                               │
│    └─→ Embedding retrieval via qwen3-embedding             │
│        └─→ Memory backend search                           │
│            └─→ BLOQUEADO AQUÍ (timeout: 8084ms)             │
│                                                             │
│ 2. LLM Summarization (never reached)                        │
│    └─→ Summary generation                                   │
└─────────────────────────────────────────────────────────────┘

Factores Contribuyentes

  1. Propagación del Timeout en Ejecución Embebida: La entrada de log embedded_run_failover_decision indica que el timeout de Active Memory se propaga al contexto de ejecución embebida, causando el log de decisión de failover. Esto sugiere un acoplamiento estrecho entre las fases de recuperación de memoria y generación de respuesta.

  2. Consulta Síncrona al Backend de Memoria: La búsqueda de memoria utiliza recuperación de embeddings síncrona. Cuando qwen3-embedding experimenta latencia (viaje de red a Ollama, carga del modelo, u overhead de búsqueda vectorial), el retraso acumulativo excede el timeout de 8000ms antes de que se genere el primer token.

  3. Timing de Verificación del Timeout: El exceso de 84-92ms (8084ms real vs. 8000ms configurado) indica que:

    • El timeout se verifica después de que cada operación bloqueante se completa
    • La recuperación de embeddings en sí toma ~8084ms
    • No existe mecanismo de salida anticipada para verificaciones de timeout sub-milisegundo
  4. Configuración del Modo de Consulta: La configuración queryMode: “message” puede activar el embedding completo del mensaje en lugar de una búsqueda semántica ligera, aumentando la latencia de recuperación.

Inconsistencia Arquitectónica

El backend memory-core no implementa:

  • Recuperación de embeddings asíncrona/no bloqueante
  • Presupuestos de timeout por fase (presupuestos separados para recuperación vs. generación)
  • Terminación anticipada ante el primer resultado sustancial

🛠️ Solución paso a paso

Solución 1: Aumentar el Timeout de Active Memory (Mitigación Inmediata)

Aumenta el timeout para acomodar la latencia de recuperación de embeddings:

Antes:

"active-memory": {
  "enabled": true,
  "config": {
    "timeoutMs": 8000,
    ...
  }
}

Después:

"active-memory": {
  "enabled": true,
  "config": {
    "timeoutMs": 30000,
    ...
  }
}

Solución 2: Separar los Timeout de Recuperación y Generación

Configura presupuestos de timeout separados para la recuperación de embeddings vs. la generación del LLM:

"active-memory": {
  "enabled": true,
  "config": {
    "timeoutMs": 30000,
    "retrievalTimeoutMs": 10000,
    "generationTimeoutMs": 20000,
    ...
  }
}

Solución 3: Cambiar a Modo de Consulta Asíncrono/Ligero

Cambia queryMode de “message” a “semantic” o “hybrid”:

Antes:

"queryMode": "message"

Después:

"queryMode": "semantic"

Solución 4: Usar un Modelo de Embedding Más Rápido

Reemplaza qwen3-embedding con un modelo de embedding local más rápido:

"active-memory": {
  "config": {
    "embeddingModel": "ollama/nomic-embed-text"
  }
}

Luego reinicia Ollama para asegurar que el modelo esté en caché:

ollama pull nomic-embed-text
systemctl restart ollama

Solución 5: Deshabilitar Active Memory Temporalmente (Para Producción)

Si el timeout está bloqueando producción, deshabilita la recuperación bloqueante:

"active-memory": {
  "enabled": false
}

O restringe al modo no bloqueante:

"active-memory": {
  "config": {
    "blockingMode": false,
    "asyncRecall": true
  }
}

Solución 6: Verificación de Salud del Backend de Memoria

Verifica la conectividad del backend de memoria y el estado de indexación:

# Check memory backend status
openclaw memory status

# Verify embedding model availability
ollama list | grep qwen3-embedding

# Test memory search latency manually
openclaw memory search "test query" --verbose

🧪 Verificación

Pasos de Verificación Después de Aplicar las Soluciones

Paso 1: Habilitar Logging Verboso y de Trazas

/verbose on
/trace on

Paso 2: Activar la Recuperación de Active Memory

Envía un mensaje que deba activar la recuperación de memoria:

what was my last message to you

Paso 3: Verificar Comportamiento Sin Timeout

Salida esperada (éxito):


🧩 Active Memory: completed 2341ms message 87 chars
🔎 Active Memory Debug: retrieved summary "User asked about..."

Log esperado del gateway:


active-memory ... done status=success elapsedMs=2345 summaryChars=87

Paso 4: Confirmar Que No Se Activó Failover

Verificar ausencia de:


embedded_run_failover_decision ... failoverReason=timeout

Paso 5: Ejecutar Comando de Diagnóstico

openclaw memory test --mode recall --verbose

Salida esperada:


Memory recall test: PASS
Retrieval latency: 1243ms
Generation latency: 892ms
Total: 2135ms (within timeout budget)

Paso 6: Verificar la Salud del Backend de Memoria

openclaw memory status

La salida esperada debe mostrar:

  • backend: memory-core
  • indexed: true
  • embedding: qwen3-embedding (o modelo configurado)
  • status: healthy

⚠️ Errores comunes

  • Timeout Demasiado Cerca de la Latencia de Embedding: Configurar timeoutMs solo ligeramente más alto que el tiempo típico de recuperación de embeddings no deja presupuesto para la generación del LLM. Asegúrate de que el timeout total acomode ambas fases más un margen de seguridad del 20%.

  • Modelo de Ollama No Precargado: En la primera solicitud, Ollama descarga y carga el modelo de embedding, causando latencia significativa. Siempre precarga los modelos:

    ollama pull ollama/gemma4:e4b
    ollama pull qwen3-embedding
  • Latencia de Red con Ollama Remoto: Si Ollama se ejecuta en un host remoto o contenedor Docker, la latencia de red se suma al tiempo de recuperación de embeddings. Usa Ollama local o aumenta el timeout en 2-3x.

  • Índice de Memoria No Construido: Si el backend de memoria no tiene contenido indexado, el paso de recuperación puede ejecutar consultas de embedding contra resultados vacíos, causando latencia inesperada. Verifica el estado del índice antes de solucionar el timeout.

  • Override del Modo Bloqueante: Algunas configuraciones o plugins pueden forzar blockingMode: true independientemente de la configuración del usuario. Verifica:

    openclaw config get active-memory.blockingMode
  • Especificidades de Discord DM: El problema se observó en contexto de Discord DM. Otras plataformas (Slack, Teams, terminal) pueden tener diferentes comportamientos de timeout debido a diferencias en la implementación del gateway.

  • Desajuste de Versión: El problema se reportó en 2026.4.12 pero menciona 26.4.14. Asegúrate de que tanto el cliente como el gateway estén en la misma versión, ya que el manejo de timeout puede haber cambiado entre versiones.

  • Operaciones de Memoria Concurrentes: Si múltiples operaciones de memoria se ejecutan concurrentemente (indexación, búsqueda, recuperación), pueden competir por los recursos del modelo de embedding. Cola las operaciones de memoria o usa instancias de embedding dedicadas.

🔗 Errores relacionados

  • embedded_run_failover_decision: Decisión de failover activada por la propagación del timeout desde la recuperación bloqueante de Active Memory al contexto de ejecución embebida.

  • memory.search.timeout: La operación de búsqueda del backend de memoria excedió su umbral de timeout (puede ocurrir independientemente o como parte del fallo de Active Memory).

  • embedding.model.not_found: El modelo de embedding configurado (qwen3-embedding) no está disponible en Ollama, causando retrasos de fallback síncrono antes del timeout.

  • active-memory.summary_chars=0: Active Memory completó pero generó cero caracteres, indicando que la fase de resumación fue omitida o falló silenciosamente.

  • gateway.active_memory.done.status=timeout: Estado a nivel de gateway indicando que la operación de Active Memory completó con estado timeout, distinto de status=success o status=error.

  • llm.context.window.exceeded: Puede ocurrir si el resumen de recuperación de memoria se incluye en solicitudes posteriores y excede los límites de contexto, relacionado con la configuración incorrecta de maxSummaryChars.

  • Histórico: Regresiones del Backend de Memoria en v2026.3.x: Versiones anteriores tenían problemas conocidos con la latencia de recuperación de memoria debido a la inicialización del backend. Asegura una reconstrucción fresca del índice después de actualizar.

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.