Si usas OpenClaw para tener un agente de IA accesible por WhatsApp, sabes que la experiencia es increíble... hasta que deja de funcionar. Un reinicio del gateway, un token expirado, un DNS que falla — y de repente tu agente está muerto y nadie te avisa.

En este post te explico cómo configuré mi setup para que sea prácticamente indestructible: reconexión automática de WhatsApp, un watchdog que revisa cada 15 minutos, y 4 proveedores de modelo en cadena de failover para que si uno se cae, el siguiente entre inmediatamente.

🦞 ¿Qué es OpenClaw?

OpenClaw es una plataforma open-source para crear agentes de IA con acceso a canales de mensajería (WhatsApp, Telegram, etc.), herramientas del sistema, y múltiples proveedores de modelos. Básicamente, un agente que vive en tu terminal y responde por WhatsApp.

1. El Problema

Todo empezó cuando noté que mi agente de OpenClaw había dejado de responder por WhatsApp. Le mandaba mensajes y nada. Silencio absoluto.

Al revisar los logs, encontré dos errores que se estaban encadenando:

⚠️ Error 1: DNS temporal — ENOTFOUND

El gateway de WhatsApp no podía resolver web.whatsapp.com. Esto pasa cuando hay una interrupción de red momentánea o el gateway se reinicia y la resolución DNS aún no está lista.

[ERROR] WhatsApp channel disconnected
  reason: getaddrinfo ENOTFOUND web.whatsapp.com
  at: 2026-02-13T08:42:17.003Z
  retry_count: 3
  status: STOPPED

⚠️ Error 2: Token de Copilot expirado — HTTP 403

El proveedor principal (GitHub Copilot) estaba devolviendo 403 Forbidden. El token de autenticación había expirado y no se renovó automáticamente. Resultado: aún cuando el canal se reconectara, el agente no podía generar respuestas.

[ERROR] Model provider failed: github-copilot/claude-opus-4.6
  status: 403 Forbidden
  message: "Token expired or revoked"
  fallback: none configured

O sea: doble falla. El canal de comunicación muerto Y el proveedor de modelo muerto. Sin fallback. Sin watchdog. Sin recuperación automática. Un desastre.

2. Diagnóstico

Antes de arreglar nada, hay que entender qué pasó. OpenClaw tiene comandos muy útiles para diagnosticar el estado de todo el sistema.

Revisar el estado de los canales

openclaw channels status

Esto muestra el estado de cada canal conectado. En mi caso, WhatsApp aparecía como STOPPED:

Channel      Status      Last Activity         Uptime
─────────    ────────    ──────────────────    ──────
whatsapp     STOPPED     2026-02-13 08:42      0s
terminal     CONNECTED   2026-02-14 10:15      1d 2h

Revisar los logs del canal

openclaw channels logs --channel whatsapp --tail 50

Aquí es donde encontré los errores de DNS que mencioné arriba. Los logs te dan el detalle completo de qué pasó y cuándo.

Health check general

openclaw health
Component          Status    Details
──────────         ──────    ───────
Gateway            ✔ OK     pid: 48291, uptime: 1d 2h
WhatsApp Channel   ✘ FAIL   STOPPED - ENOTFOUND web.whatsapp.com
Model: openai      ✔ OK     gpt-5.3-codex responding
Model: copilot     ✘ FAIL   403 Forbidden - token expired
Node.js            ✔ OK     v22.14.0
Cron               ✔ OK     0 active jobs

💡 Pro tip

Siempre corre openclaw health primero. Te da una vista panorámica de todo lo que está bien y mal en un solo comando. Desde ahí sabes dónde enfocarte.

3. Solución 1: Reconectar WhatsApp

Lo primero es lo primero: restaurar la conexión del canal de WhatsApp.

Paso 1: Re-autenticar el canal

openclaw channels login --channel whatsapp

Esto regenera la sesión de WhatsApp. Te va a pedir escanear un código QR desde tu teléfono (igual que WhatsApp Web). Una vez escaneado, la sesión queda activa.

Paso 2: Reiniciar el gateway

openclaw gateway restart

El gateway es el proceso que mantiene las conexiones activas. Al reiniciarlo, se reconectan todos los canales con las sesiones actualizadas.

Gateway restarting...
  WhatsApp: reconnecting... ✔ CONNECTED
  Terminal: reconnecting... ✔ CONNECTED
Gateway ready (pid: 51023)

Paso 3: Verificar

openclaw channels status

Channel      Status       Last Activity         Uptime
─────────    ─────────    ──────────────────    ──────
whatsapp     CONNECTED    2026-02-14 10:30      2m
terminal     CONNECTED    2026-02-14 10:30      1d 2h

✔ Canal restaurado

WhatsApp vuelve a estar CONNECTED. Pero esto fue un fix manual. Si se vuelve a caer a las 3am, ¿quién lo reconecta? Nadie. Por eso necesitamos el watchdog.

4. Solución 2: Watchdog Automático (Cron)

La idea es simple: un cron job que corre cada 15 minutos, revisa si WhatsApp está conectado, y si no lo está, lo reconecta automáticamente. Lo mejor es que OpenClaw tiene esto integrado — no necesitas crontab del sistema ni scripts externos.

Crear el watchdog

openclaw cron add \
  --name "whatsapp-watchdog" \
  --every 15m \
  --message "Revisa el estado del canal de WhatsApp. Si está desconectado o stopped, ejecuta 'openclaw gateway restart' para reconectarlo." \
  --channel whatsapp \
  --to "+52XXXXXXXXXX" \
  --best-effort-deliver

¿Qué hace esto exactamente?

🔄 ¿Cómo funciona internamente?

El cron de OpenClaw no es un crontab de Unix. Es un scheduler interno que vive en el gateway. Cada 15 minutos, invoca al agente con el mensaje que le diste, el agente analiza el estado usando sus herramientas (channels_status, gateway_restart, etc.) y toma las acciones necesarias. Es como tener un DevOps bot viviendo en tu máquina.

Verificar que el cron está activo

openclaw cron list

Name                  Interval    Next Run              Channel     Status
────────────────      ────────    ──────────────────    ─────────   ──────
whatsapp-watchdog     15m         2026-02-14 10:45      whatsapp    ACTIVE

✔ Watchdog activo

Ahora si WhatsApp se desconecta a las 3am, el watchdog lo detecta en máximo 15 minutos y lo reconecta solo. Puedes dormir tranquilo.

5. Solución 3: Multi-Provider Failover

El canal ya se reconecta solo. Pero ¿qué pasa si el modelo falla? Si tu único proveedor es GitHub Copilot y el token expira, el agente recibe mensajes pero no puede responder. Necesitamos un plan B. Y un plan C. Y un plan D.

La cadena de failover

Prioridad Proveedor Modelo Notas
Primary OpenAI Codex openai-codex/gpt-5.3-codex El más rápido, ideal para respuestas del día a día
Fallback #1 GitHub Copilot github-copilot/claude-opus-4.6 Claude Opus vía Copilot proxy, muy capaz
Fallback #2 Copilot Proxy copilot-proxy/claude-sonnet-4.5 Sonnet vía Copilot, más ligero pero confiable
Fallback #3 Anthropic (Claude Code) anthropic/claude-sonnet-4-5-20250929 Directo desde Claude Code subscription

La lógica es: si el proveedor primario falla (timeout, 403, 500, rate limit), OpenClaw automáticamente intenta el siguiente en la lista. Si ese también falla, pasa al siguiente. Así sucesivamente hasta que uno responda.

Configurar los fallbacks

openclaw config set agents.defaults.model.fallbacks \
  '["github-copilot/claude-opus-4.6","copilot-proxy/claude-sonnet-4.5","anthropic/claude-sonnet-4-5-20250929"]' \
  --json
✔ Config updated: agents.defaults.model.fallbacks
   [0] github-copilot/claude-opus-4.6
   [1] copilot-proxy/claude-sonnet-4.5
   [2] anthropic/claude-sonnet-4-5-20250929

💡 ¿Por qué este orden?

El modelo primario (openai-codex/gpt-5.3-codex) ya está configurado como default. Los fallbacks se prueban en orden. Puse Claude Opus primero porque es el más capaz. Sonnet como segundo porque es rápido y barato. Y el de Anthropic directo como último recurso porque usa los créditos de mi suscripción de Claude Code.

6. Configurar GitHub Copilot como Provider

Para que OpenClaw pueda usar modelos vía GitHub Copilot, necesitas autenticarte con el device flow de GitHub:

openclaw models auth login-github-copilot
🔐 GitHub Copilot Authentication
   Open this URL in your browser:
   → https://github.com/login/device

   Enter this code: ABCD-1234

   Waiting for authorization...

El proceso es:

  1. Abre https://github.com/login/device en tu navegador.
  2. Ingresa el código que te muestra la terminal.
  3. Autoriza el acceso.
  4. La terminal detecta la autorización automáticamente.
   ✔ Authenticated as @oscarcode9
   Token stored securely.
   Available models: claude-opus-4.6, claude-sonnet-4.5, gpt-4o, o1...

⚠️ Token expiration

Los tokens de Copilot expiran periódicamente. Si ves errores 403, re-ejecuta openclaw models auth login-github-copilot para renovar. Con el failover configurado, incluso si el token expira, los otros proveedores toman el relevo mientras lo renuevas.

7. Configurar Claude Code como Provider

Esta es la parte más elegante del setup. OpenClaw puede leer las credenciales de Claude Code directamente desde el macOS Keychain. Si ya tienes Claude Code instalado y autenticado, no necesitas configurar tokens ni API keys manualmente.

🔑 Credenciales automáticas

OpenClaw busca las credenciales en el Keychain de macOS bajo el nombre Claude Code-credentials. Si Claude Code está autenticado en tu máquina, OpenClaw las encuentra y las usa directamente. Zero config.

Lo único que necesitas hacer es decirle a OpenClaw que ese modelo existe como opción:

openclaw config set agents.defaults.models.anthropic/claude-sonnet-4-5-20250929 '{}' --json
✔ Config updated: agents.defaults.models.anthropic/claude-sonnet-4-5-20250929
   Auth: macOS Keychain (Claude Code-credentials) ✔
   Model: claude-sonnet-4-5-20250929
   Status: ready

Eso es todo. El {} vacío significa “usa las credenciales que ya tienes”. OpenClaw detecta el Keychain, extrae el token, y lo usa cuando necesita hacer requests a la API de Anthropic.

💡 ¿Por qué es el último fallback?

Porque los requests a la API directa de Anthropic se descuentan de tu suscripción de Claude Code. Los otros proveedores (Copilot) usan sus propios créditos. Entonces reservo Anthropic directo como último recurso para no gastar créditos innecesariamente.

8. Instalar Node.js del Sistema

El gateway de OpenClaw corre sobre Node.js. Si estás usando la versión que viene con algún version manager (nvm, fnm, etc.), puede haber problemas de estabilidad cuando el gateway se ejecuta como proceso de fondo — especialmente después de reinicios del sistema.

La solución es instalar Node.js directamente con Homebrew para que esté disponible a nivel de sistema:

brew install node

Después, ejecuta el doctor de OpenClaw para que detecte y use la instalación del sistema:

openclaw doctor --fix
🔍 Running diagnostics...

  Node.js        ✔  v22.14.0 (/opt/homebrew/bin/node)
  npm            ✔  v10.9.2
  Gateway        ✔  running (pid: 51023)
  WhatsApp       ✔  CONNECTED
  Models         ✔  4 configured (1 primary + 3 fallbacks)
  Cron           ✔  1 active job
  Keychain       ✔  Claude Code-credentials found

✔ All checks passed. No fixes needed.

✔ Sistema estable

Con Node.js instalado vía Homebrew, el gateway tiene una instalación de Node confiable que no depende de la sesión de shell ni de variables de entorno de nvm. Esto es especialmente importante para que el watchdog funcione correctamente en background.

9. Verificar Todo

Ya tenemos todo configurado. Ahora hay que probar que cada proveedor funciona y que el canal de WhatsApp entrega los mensajes correctamente.

Probar el envío por WhatsApp

openclaw agent \
  -m "Responde con: Soy [provider] y estoy funcionando" \
  --to "+52XXXXXXXXXX" \
  --channel whatsapp \
  --deliver

Si todo está bien, deberías recibir un mensaje en WhatsApp con el nombre del proveedor que respondió.

Verificar la configuración de modelos

openclaw models list
Role          Provider                Model                              Status
──────────    ──────────────────      ─────────────────────────────      ──────
default       openai-codex            gpt-5.3-codex                      ✔ OK
fallback#1    github-copilot          claude-opus-4.6                    ✔ OK
fallback#2    copilot-proxy           claude-sonnet-4.5                  ✔ OK
fallback#3    anthropic               claude-sonnet-4-5-20250929         ✔ OK

Los 4 proveedores deben mostrar OK. Si alguno muestra error, revisa la autenticación de ese proveedor específico.

Probar el failover manualmente

Para verificar que el failover funciona, puedes forzar una falla temporal en el proveedor primario:

# Deshabilitar temporalmente el proveedor primario
openclaw config set agents.defaults.model.enabled false

# Enviar un mensaje — debería usar fallback#1
openclaw agent -m "¿Qué modelo me está respondiendo?" --to "+52XXXXXXXXXX" --channel whatsapp --deliver

# Re-habilitar el proveedor primario
openclaw config set agents.defaults.model.enabled true

✔ Failover verificado

Si recibes respuesta cuando el primario está deshabilitado, el failover está funcionando correctamente. El agente cambió automáticamente al siguiente proveedor disponible.

10. Resultado Final

Aquí está el diagrama completo del flujo de failover:

📱 WhatsApp Message │ ▼ ┌─────────────────────────┐ │ OpenClaw Gateway │◄──── Watchdog (cada 15min) │ (Node.js process) │ reconecta si STOPPED └────────┬────────────────┘ │ ▼ ┌─────────────────────────┐ │ Model Router │ │ (failover chain) │ └────────┬────────────────┘ │ ┌─────┴───────────────────────────────────────┐ │ │ ▼ │ ┌──────────────────┐ │ │ PRIMARY │──── OK ──── Responde ──▶ 📱│ │ openai-codex/ │ │ │ gpt-5.3-codex │ │ └──────┬───────────┘ │ │ FAIL │ ▼ │ ┌──────────────────┐ │ │ FALLBACK #1 │──── OK ──── Responde ──▶ 📱│ │ github-copilot/ │ │ │ claude-opus-4.6 │ │ └──────┬───────────┘ │ │ FAIL │ ▼ │ ┌──────────────────┐ │ │ FALLBACK #2 │──── OK ──── Responde ──▶ 📱│ │ copilot-proxy/ │ │ │ claude-sonnet-4.5│ │ └──────┬───────────┘ │ │ FAIL │ ▼ │ ┌──────────────────┐ │ │ FALLBACK #3 │──── OK ──── Responde ──▶ 📱│ │ anthropic/ │ │ │ claude-sonnet-4-5│ │ │ (Claude Code) │ │ └──────────────────┘ │ │ ◄─────────────────────────────────────────────────┘

Resumen de lo que configuramos

🦞 Setup Final

Un agente de OpenClaw que es prácticamente indestructible:

Componente Qué hace Estado
WhatsApp Channel Canal de comunicación principal ✔ CONNECTED
Watchdog Cron Revisa WhatsApp cada 15 min, reconecta si se cae ✔ ACTIVE
4 Proveedores Cadena de failover automática de modelos ✔ 4/4 OK
Node.js (Homebrew) Runtime estable a nivel de sistema ✔ v22.14.0
Claude Code Keychain Credenciales Anthropic sin configuración manual ✔ Auto-detected

Con esta configuración, el agente puede sobrevivir:

El único escenario que no está cubierto es si los 4 proveedores fallan al mismo tiempo. Spoiler: sí pasó. Sigue leyendo.

11. Post-Mortem: Cuando el Failover No Failoverea

Plot twist: después de configurar todo lo anterior, el bot se volvió a caer. Le mandaba mensajes por WhatsApp y respondía "Connection error." como texto literal. La cadena de failover estaba configurada... pero no funcionaba.

⚠️ El error real

Al revisar los logs del agente, encontré esto: FailoverError: No API key found for provider "anthropic". Auth store: ~/.openclaw/agents/main/agent/auth-profiles.json. Anthropic fallaba porque sus credenciales no estaban en el auth-profiles del agente.

¿Qué pasó?

El problema fue que configuramos el modelo de Anthropic en openclaw.json (la config global), pero nunca copiamos las credenciales al archivo de autenticación del agente. OpenClaw separa la configuración de modelos de la autenticación:

OpenAI y GitHub Copilot sí tenían sus credenciales ahí. Anthropic no. Entonces cuando OpenAI fallaba y GitHub Copilot estaba en cooldown por rate limit, el failover intentaba Anthropic... y también fallaba. El agente se quedaba sin opciones y respondía con el error como texto.

El fix: Registrar las credenciales de Claude Code en el agente

Las credenciales de Claude Code viven en el macOS Keychain. Hay que copiarlas al auth-profiles.json del agente para que el failover pueda usarlas:

# 1. Extraer las credenciales del Keychain
security find-generic-password -s "Claude Code-credentials" -w

Esto devuelve un JSON con accessToken, refreshToken, y expiresAt. Luego hay que agregarlos al auth-profiles:

# 2. Agregar perfil de Anthropic en auth-profiles.json
# Archivo: ~/.openclaw/agents/main/agent/auth-profiles.json
# Agregar dentro de "profiles":

"anthropic:claude-code": {
  "type": "oauth",
  "provider": "anthropic",
  "access": "sk-ant-oat01-...",   // accessToken del Keychain
  "refresh": "sk-ant-ort01-...",  // refreshToken del Keychain
  "expires": 1757037189278         // expiresAt del Keychain
}

# Y agregar en "lastGood":
"anthropic": "anthropic:claude-code"

Después de agregar las credenciales, reiniciar el gateway:

openclaw gateway restart

El otro bug: el watchdog no encontraba openclaw

El cron watchdog ejecutaba openclaw gateway restart pero fallaba con zsh:1: command not found: openclaw. El gateway corre como un proceso de fondo (LaunchAgent) y su shell no tiene el mismo PATH que tu terminal.

La solución: usar la ruta absoluta del binario en el mensaje del cron:

# Antes (fallaba en background):
"Ejecuta 'openclaw gateway restart' para reconectarlo."

# Después (funciona siempre):
"Ejecuta '/ruta/completa/a/openclaw gateway restart' para reconectarlo."

✔ Lección aprendida

Configurar el failover tiene dos partes: (1) registrar los modelos en la config global, y (2) asegurarte de que las credenciales de cada proveedor estén en el auth-profiles.json del agente. Si falta cualquiera de las dos, el failover no funciona. Y para cron jobs, siempre usa rutas absolutas.

12. Checklist Final

Para asegurarte de que tu setup está completo y no te pase lo que a mí, revisa cada punto:

Check Comando Qué verificar
WhatsApp conectado openclaw channels status Status = CONNECTED
Modelo primario responde openclaw agent -m "ping" --deliver Recibes respuesta en WhatsApp
Fallbacks configurados openclaw config get agents.defaults.model Primary + fallbacks listados
Auth de CADA proveedor Revisar auth-profiles.json Todos los fallbacks tienen credenciales
Watchdog activo openclaw cron list whatsapp-watchdog = ACTIVE
Watchdog usa ruta absoluta Revisar cron/jobs.json Ruta completa al binario openclaw

🦞 Para los que quieren ir más allá

Puedes agregar más canales (Telegram, Slack) como fallback de comunicación, configurar alertas por email cuando el watchdog detecta una falla, o incluso agregar proveedores locales (Ollama, LM Studio) como último-último recurso para funcionar completamente offline. Las posibilidades con OpenClaw son infinitas.

13. La Tormenta Perfecta: Los 3 Proveedores Cayeron a la Vez

Recuerdan que dije que si los 3 proveedores fallan al mismo tiempo “tenemos problemas más grandes”? Bueno, pasó. Horas después de publicar este post, los 3 murieron simultáneamente:

💀 Error: All models failed (3)

github-copilot/claude-opus-4.6: cooldown (rate_limit)
anthropic/claude-sonnet-4-5-20250929: OAuth token refresh failed
openai-codex/gpt-5.3-codex: ChatGPT Go plan usage limit (~5936 min)

Tres fallas distintas, cada una por una razón diferente. Un rate limit, un token expirado, y un límite de plan. La combinación perfecta para dejar al bot completamente muerto.

Root cause #1: Tokens de Anthropic expirados en el Keychain

Las credenciales de Claude Code en el macOS Keychain estaban expiradas desde septiembre 2025. Claude Code funciona en memoria con tokens frescos, pero no actualiza el Keychain cuando renueva sus tokens internamente. OpenClaw lee del Keychain → obtiene tokens viejos → OAuth refresh falla → proveedor muerto.

# Verificar cuándo se modificó el Keychain:
security find-generic-password -s "Claude Code-credentials" -g 2>&1 | grep mdat
mdat=0x323032353039... (September 2025!)

Root cause #2: El cooldown exponencial en cascada

Revisé el código fuente de OpenClaw y encontré la trampa. Cuando un proveedor recibe un error 429 (rate limit), OpenClaw pone el perfil de autenticación en cooldown exponencial:

Error # Cooldown Efecto
1er error 60 segundos Pausa corta, tolerable
2do error 5 minutos Empieza a doler
3er error 25 minutos Proveedor básicamente muerto
4to+ error 1 hora (máximo) Game over

El problema: el cooldown es global por perfil. Si el gateway procesa múltiples mensajes de WhatsApp concurrentemente (o un cron job al mismo tiempo), cada request fallido incrementa el contador. En segundos, el cooldown escala de 60s a 1 hora, y todos los requests siguientes fallan instantáneamente sin siquiera intentar llamar al API.

Además, descubrí en los logs que los “rate limits” de 23 segundos en realidad eran timeouts. El API de Anthropic se colgaba (en vez de devolver 429 instantáneo), el request expiraba, y OpenClaw lo clasificaba como rate limit con el comentario en el código: // Treat timeout as potential rate limit (Antigravity hangs on rate limit).

Root cause #3: Config error que eliminó un proveedor de la cadena

Durante el debugging, cambié el modelo primario de openai-codex a anthropic para forzar pruebas directas. Esto causó que la cadena de failover pasara de 3 proveedores a 2:

# Config durante debugging (MAL):
"primary": "anthropic/claude-sonnet-4-5-20250929"    // anthropic como primario
"fallbacks": [
  "github-copilot/claude-opus-4.6",              // fallback 1
  "anthropic/claude-sonnet-4-5-20250929"          // duplicado = eliminado
]
// Resultado: solo 2 proveedores! openai-codex quedó fuera

# Config correcta:
"primary": "openai-codex/gpt-5.3-codex"               // openai como primario
"fallbacks": [
  "github-copilot/claude-opus-4.6",              // fallback 1
  "anthropic/claude-sonnet-4-5-20250929"          // fallback 2
]
// Resultado: 3 proveedores en cadena

Los logs del gateway confirmaban: All models failed (2) — no 3. OpenClaw deduplica los modelos, así que anthropic como primario + anthropic como fallback = un solo proveedor.

El fix: Tokens frescos via OAuth PKCE + restaurar la cadena

La solución tuvo 3 partes:

Parte 1: Obtener tokens frescos de Anthropic haciendo el flujo OAuth PKCE manualmente (el mismo que usa Claude Code internamente):

# 1. Generar PKCE verifier + challenge
# 2. Abrir URL de autorización en claude.ai/oauth/authorize
# 3. Copiar el código del callback
# 4. Intercambiar código por tokens frescos:
curl -X POST https://console.anthropic.com/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{"grant_type":"authorization_code","code":"...","code_verifier":"...","client_id":"...","redirect_uri":"..."}'

# Resultado: access_token + refresh_token frescos (8 horas)

Parte 2: Restaurar el modelo primario a openai-codex/gpt-5.3-codex para tener los 3 proveedores en la cadena.

Parte 3: Limpiar los cooldowns acumulados en auth-profiles.json y reiniciar el gateway:

# Limpiar cooldowns (en auth-profiles.json, cambiar usageStats a vacío):
"usageStats": {}

# Reiniciar:
openclaw gateway restart

Resultado del test después del fix:

openclaw agent --session-id "test-fix" -m "di OK"
[failover] openai-codex: rate_limit (10s) → skip
[failover] github-copilot: rate_limit (22s) → skip
[failover] anthropic: ✔ success
OK

✔ Bot restaurado

Los 2 primeros proveedores siguen con rate limit temporal, pero el tercero (Anthropic con tokens frescos) responde correctamente. La cadena de failover funciona como debe: si los primeros fallan, el tercero entra.

14. Lecciones del Incidente

  1. El Keychain miente. Claude Code funciona en memoria con tokens frescos pero no actualiza el Keychain. Si dependes del Keychain para credenciales, verifica que no estén expiradas.
  2. El cooldown exponencial es una espada de doble filo. Protege contra spam al API, pero en un escenario con múltiples requests concurrentes, un solo error escala en segundos a 1 hora de bloqueo total.
  3. Nunca cambies el primary model para “debug rápido”. Si tu primary es igual a un fallback, OpenClaw deduplica y pierdes un proveedor de la cadena sin darte cuenta.
  4. Los timeouts se clasifican como rate limits. Una respuesta lenta del API (23s timeout) cuenta igual que un 429 real. Esto acelera el cooldown exponencial artificialmente.
  5. Limpia usageStats después de arreglar la causa raíz. Si no limpias los cooldowns acumulados, el gateway sigue rechazando requests instantáneamente incluso con tokens frescos.

🦞 El setup actualizado

Después de este incidente, la cadena de failover tiene 3 proveedores activos con tokens verificados, cooldowns limpios, y el primary model correctamente configurado. La próxima vez que un proveedor falle, los otros dos entran. Y si los 3 fallan... bueno, ya sé cómo arreglarlo en 5 minutos en vez de 5 horas.