Tareas cron (programador del Gateway)

¿Cron o Heartbeat? Consulta Cron vs Heartbeat para saber cuándo usar cada uno.

Cron es el programador integrado del Gateway. Persiste las tareas, despierta al agente en el momento adecuado y opcionalmente puede devolver la salida a un chat.

Si quieres “ejecuta esto cada mañana” o “avísale al agente en 20 minutos”, cron es el mecanismo indicado.

Solución de problemas: /automation/troubleshooting

Resumen rápido

  • Cron se ejecuta dentro del Gateway (no dentro del modelo).
  • Las tareas persisten en ~/.openclaw/cron/ así que los reinicios no pierden los horarios.
  • Dos estilos de ejecución:
    • Sesión principal: encola un evento del sistema, luego se ejecuta en el próximo heartbeat.
    • Aislado: ejecuta un turno dedicado del agente en cron:<jobId>, con entrega (announce por defecto o ninguna).
  • Los despertares son de primera clase: una tarea puede solicitar “despertar ahora” vs “próximo heartbeat”.
  • El envío por webhook es por tarea vía delivery.mode = "webhook" + delivery.to = "<url>".
  • El respaldo legacy permanece para tareas almacenadas con notify: true cuando cron.webhook está configurado; migra esas tareas al modo de entrega webhook.
  • Para actualizaciones, openclaw doctor --fix puede normalizar campos legacy del almacén cron antes de que el programador los toque.

Inicio rápido (accionable)

Crea un recordatorio único, verifica que existe y ejecútalo inmediatamente:

openclaw cron add \
  --name "Reminder" \
  --at "2026-02-01T16:00:00Z" \
  --session main \
  --system-event "Reminder: check the cron docs draft" \
  --wake now \
  --delete-after-run

openclaw cron list
openclaw cron run <job-id>
openclaw cron runs --id <job-id>

Programa una tarea aislada recurrente con entrega:

openclaw cron add \
  --name "Morning brief" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize overnight updates." \
  --announce \
  --channel slack \
  --to "channel:C1234567890"

Equivalentes de llamadas a herramientas (herramienta cron del Gateway)

Para las estructuras JSON canónicas y ejemplos, consulta Esquema JSON para llamadas a herramientas.

Dónde se almacenan las tareas cron

Las tareas cron se persisten en el host del Gateway en ~/.openclaw/cron/jobs.json por defecto. El Gateway carga el archivo en memoria y lo escribe de vuelta cuando hay cambios, así que las ediciones manuales solo son seguras cuando el Gateway está detenido. Usa openclaw cron add/edit o la API de llamadas a herramientas cron para los cambios.

Descripción general para principiantes

Piensa en una tarea cron como: cuándo ejecutar + qué hacer.

  1. Elige un horario

    • Recordatorio único → schedule.kind = "at" (CLI: --at)
    • Tarea repetitiva → schedule.kind = "every" o schedule.kind = "cron"
    • Si tu marca de tiempo ISO omite zona horaria, se trata como UTC.
  2. Elige dónde se ejecuta

    • sessionTarget: "main" → ejecutar durante el próximo heartbeat con contexto principal.
    • sessionTarget: "isolated" → ejecutar un turno dedicado del agente en cron:<jobId>.
  3. Elige el payload

    • Sesión principal → payload.kind = "systemEvent"
    • Sesión aislada → payload.kind = "agentTurn"

Opcional: las tareas únicas (schedule.kind = "at") se eliminan después del éxito por defecto. Configura deleteAfterRun: false para conservarlas (se deshabilitarán después del éxito).

Conceptos

Tareas

Una tarea cron es un registro almacenado con:

  • un horario (cuándo debería ejecutarse),
  • un payload (qué debería hacer),
  • un modo de entrega opcional (announce, webhook o none).
  • una vinculación de agente opcional (agentId): ejecuta la tarea bajo un agente específico; si falta o es desconocido, el gateway recurre al agente predeterminado.

Las tareas se identifican por un jobId estable (usado por las APIs del CLI/Gateway). En las llamadas a herramientas del agente, jobId es canónico; el legacy id se acepta por compatibilidad. Las tareas únicas se auto-eliminan después del éxito por defecto; configura deleteAfterRun: false para conservarlas.

Horarios

Cron soporta tres tipos de horario:

  • at: marca de tiempo única vía schedule.at (ISO 8601).
  • every: intervalo fijo (ms).
  • cron: expresión cron de 5 campos (o 6 campos con segundos) con zona horaria IANA opcional.

Las expresiones cron usan croner. Si se omite la zona horaria, se usa la zona horaria local del host del Gateway.

Para reducir picos de carga al inicio de la hora en muchos gateways, OpenClaw aplica una ventana de desfase determinístico por tarea de hasta 5 minutos para expresiones recurrentes de inicio de hora (por ejemplo 0 * * * *, 0 */2 * * *). Las expresiones de hora fija como 0 7 * * * permanecen exactas.

Para cualquier horario cron, puedes establecer una ventana de desfase explícita con schedule.staggerMs (0 mantiene la temporización exacta). Atajos CLI:

  • --stagger 30s (o 1m, 5m) para establecer una ventana de desfase explícita.
  • --exact para forzar staggerMs = 0.

Ejecución en sesión principal vs aislada

Tareas de sesión principal (eventos del sistema)

Las tareas principales encolan un evento del sistema y opcionalmente despiertan el ejecutor de heartbeat. Deben usar payload.kind = "systemEvent".

  • wakeMode: "now" (predeterminado): el evento dispara una ejecución inmediata del heartbeat.
  • wakeMode: "next-heartbeat": el evento espera al próximo heartbeat programado.

Este es el mejor ajuste cuando quieres el prompt de heartbeat normal + contexto de sesión principal. Consulta Heartbeat.

Tareas aisladas (sesiones cron dedicadas)

Las tareas aisladas ejecutan un turno dedicado del agente en la sesión cron:<jobId>.

Comportamientos clave:

  • El prompt se prefija con [cron:<jobId> <nombre de tarea>] para trazabilidad.
  • Cada ejecución inicia un ID de sesión fresco (sin arrastre de conversación previa).
  • Comportamiento predeterminado: si se omite delivery, las tareas aisladas anuncian un resumen (delivery.mode = "announce").
  • delivery.mode elige qué ocurre:
    • announce: entrega un resumen al canal destino y publica un resumen breve en la sesión principal.
    • webhook: hace POST del payload del evento finalizado a delivery.to cuando el evento finalizado incluye un resumen.
    • none: solo interno (sin entrega, sin resumen en sesión principal).
  • wakeMode controla cuándo se publica el resumen en la sesión principal:
    • now: heartbeat inmediato.
    • next-heartbeat: espera al próximo heartbeat programado.

Usa tareas aisladas para trabajos ruidosos, frecuentes o “tareas de fondo” que no deberían saturar el historial de tu chat principal.

Formas del payload (qué se ejecuta)

Se soportan dos tipos de payload:

  • systemEvent: solo sesión principal, enrutado a través del prompt de heartbeat.
  • agentTurn: solo sesión aislada, ejecuta un turno dedicado del agente.

Campos comunes de agentTurn:

  • message: prompt de texto requerido.
  • model / thinking: sobreescrituras opcionales (ver abajo).
  • timeoutSeconds: sobreescritura opcional de timeout.
  • lightContext: modo opcional de bootstrap ligero para tareas que no necesitan inyección de archivos de bootstrap del workspace.

Configuración de entrega:

  • delivery.mode: none | announce | webhook.
  • delivery.channel: last o un canal específico.
  • delivery.to: destino específico del canal (announce) o URL del webhook (modo webhook).
  • delivery.bestEffort: evitar que la tarea falle si la entrega announce falla.

La entrega announce suprime los envíos de la herramienta de mensajería para la ejecución; usa delivery.channel/delivery.to para apuntar al chat en su lugar. Cuando delivery.mode = "none", no se publica resumen en la sesión principal.

Si se omite delivery para tareas aisladas, OpenClaw usa announce por defecto.

Flujo de entrega announce

Cuando delivery.mode = "announce", cron entrega directamente vía los adaptadores de canal de salida. El agente principal no se activa para componer o reenviar el mensaje.

Detalles del comportamiento:

  • Contenido: la entrega usa los payloads de salida de la ejecución aislada (texto/medios) con el chunking y formato de canal normales.
  • Las respuestas solo-heartbeat (HEARTBEAT_OK sin contenido real) no se entregan.
  • Si la ejecución aislada ya envió un mensaje al mismo destino vía la herramienta de mensajes, la entrega se omite para evitar duplicados.
  • Destinos de entrega faltantes o inválidos hacen fallar la tarea a menos que delivery.bestEffort = true.
  • Se publica un resumen corto en la sesión principal solo cuando delivery.mode = "announce".
  • El resumen en la sesión principal respeta wakeMode: now dispara un heartbeat inmediato y next-heartbeat espera al próximo heartbeat programado.

Flujo de entrega webhook

Cuando delivery.mode = "webhook", cron hace POST del payload del evento finalizado a delivery.to cuando el evento finalizado incluye un resumen.

Detalles del comportamiento:

  • El endpoint debe ser una URL HTTP(S) válida.
  • No se intenta entrega por canal en modo webhook.
  • No se publica resumen en sesión principal en modo webhook.
  • Si cron.webhookToken está configurado, el header de auth es Authorization: Bearer <cron.webhookToken>.
  • Respaldo deprecado: las tareas legacy almacenadas con notify: true aún publican a cron.webhook (si está configurado), con una advertencia para que migres a delivery.mode = "webhook".

Sobreescrituras de modelo y razonamiento

Las tareas aisladas (agentTurn) pueden sobreescribir el modelo y nivel de razonamiento:

  • model: cadena proveedor/modelo (por ejemplo, anthropic/claude-sonnet-4-20250514) o alias (por ejemplo, opus)
  • thinking: nivel de razonamiento (off, minimal, low, medium, high, xhigh; solo modelos GPT-5.2 + Codex)

Nota: puedes configurar model en tareas de sesión principal también, pero cambia el modelo compartido de la sesión principal. Recomendamos sobreescrituras de modelo solo para tareas aisladas para evitar cambios inesperados de contexto.

Prioridad de resolución:

  1. Sobreescritura del payload de la tarea (más alta)
  2. Valores predeterminados específicos del hook (por ejemplo, hooks.gmail.model)
  3. Valor predeterminado de la configuración del agente

Contexto de bootstrap ligero

Las tareas aisladas (agentTurn) pueden configurar lightContext: true para ejecutarse con contexto de bootstrap ligero.

  • Usa esto para tareas programadas que no necesitan inyección de archivos de bootstrap del workspace.
  • En la práctica, el runtime embebido se ejecuta con bootstrapContextMode: "lightweight", que mantiene el contexto de bootstrap de cron vacío a propósito.
  • Equivalentes CLI: openclaw cron add --light-context ... y openclaw cron edit --light-context.

Entrega (canal + destino)

Las tareas aisladas pueden entregar salida a un canal vía la configuración de delivery de nivel superior:

  • delivery.mode: announce (entrega por canal), webhook (HTTP POST) o none.
  • delivery.channel: whatsapp / telegram / discord / slack / mattermost (plugin) / signal / imessage / last.
  • delivery.to: destino del destinatario específico del canal.

La entrega announce solo es válida para tareas aisladas (sessionTarget: "isolated"). La entrega webhook es válida tanto para tareas principales como aisladas.

Si se omite delivery.channel o delivery.to, cron puede recurrir a la “última ruta” de la sesión principal (el último lugar donde el agente respondió).

Recordatorios de formato del destino:

  • Los destinos de Slack/Discord/Mattermost (plugin) deben usar prefijos explícitos (por ejemplo, channel:<id>, user:<id>) para evitar ambigüedad. Los IDs desnudos de 26 caracteres de Mattermost se resuelven primero como usuario (DM si el usuario existe, canal en caso contrario) — usa user:<id> o channel:<id> para enrutamiento determinístico.
  • Los temas de Telegram deben usar la forma :topic: (ver abajo).

Destinos de entrega en Telegram (temas / hilos de foro)

Telegram soporta temas de foro vía message_thread_id. Para la entrega cron, puedes codificar el tema/hilo en el campo to:

  • -1001234567890 (solo ID de chat)
  • -1001234567890:topic:123 (preferido: marcador de tema explícito)
  • -1001234567890:123 (abreviatura: sufijo numérico)

Los destinos con prefijo como telegram:... / telegram:group:... también se aceptan:

  • telegram:group:-1001234567890:topic:123

Esquema JSON para llamadas a herramientas

Usa estas estructuras cuando llames directamente a las herramientas cron.* del Gateway (llamadas a herramientas del agente o RPC). Los flags del CLI aceptan duraciones legibles como 20m, pero las llamadas a herramientas deben usar una cadena ISO 8601 para schedule.at y milisegundos para schedule.everyMs.

Parámetros de cron.add

Tarea única, sesión principal (evento del sistema):

{
  "name": "Reminder",
  "schedule": { "kind": "at", "at": "2026-02-01T16:00:00Z" },
  "sessionTarget": "main",
  "wakeMode": "now",
  "payload": { "kind": "systemEvent", "text": "Reminder text" },
  "deleteAfterRun": true
}

Tarea recurrente, aislada con entrega:

{
  "name": "Morning brief",
  "schedule": { "kind": "cron", "expr": "0 7 * * *", "tz": "America/Los_Angeles" },
  "sessionTarget": "isolated",
  "wakeMode": "next-heartbeat",
  "payload": {
    "kind": "agentTurn",
    "message": "Summarize overnight updates.",
    "lightContext": true
  },
  "delivery": {
    "mode": "announce",
    "channel": "slack",
    "to": "channel:C1234567890",
    "bestEffort": true
  }
}

Notas:

  • schedule.kind: at (at), every (everyMs) o cron (expr, tz opcional).
  • schedule.at acepta ISO 8601 (zona horaria opcional; se trata como UTC cuando se omite).
  • everyMs está en milisegundos.
  • sessionTarget debe ser "main" o "isolated" y debe coincidir con payload.kind.
  • Campos opcionales: agentId, description, enabled, deleteAfterRun (por defecto true para at), delivery.
  • wakeMode por defecto es "now" cuando se omite.

Parámetros de cron.update

{
  "jobId": "job-123",
  "patch": {
    "enabled": false,
    "schedule": { "kind": "every", "everyMs": 3600000 }
  }
}

Notas:

  • jobId es canónico; id se acepta por compatibilidad.
  • Usa agentId: null en el patch para limpiar una vinculación de agente.

Parámetros de cron.run y cron.remove

{ "jobId": "job-123", "mode": "force" }
{ "jobId": "job-123" }

Almacenamiento e historial

  • Almacén de tareas: ~/.openclaw/cron/jobs.json (JSON gestionado por el Gateway).
  • Historial de ejecuciones: ~/.openclaw/cron/runs/<jobId>.jsonl (JSONL, auto-podado por tamaño y conteo de líneas).
  • Las sesiones de ejecución cron aisladas en sessions.json se podan por cron.sessionRetention (por defecto 24h; configura false para deshabilitar).
  • Sobreescribir ruta del almacén: cron.store en la configuración.

Política de reintentos

Cuando una tarea falla, OpenClaw clasifica los errores como transitorios (reintentables) o permanentes (deshabilitar inmediatamente).

Errores transitorios (reintentados)

  • Límite de tasa (429, too many requests, resource exhausted)
  • Sobrecarga del proveedor (por ejemplo, Anthropic 529 overloaded_error, resúmenes de respaldo por sobrecarga)
  • Errores de red (timeout, ECONNRESET, fetch failed, socket)
  • Errores de servidor (5xx)
  • Errores relacionados con Cloudflare

Errores permanentes (sin reintento)

  • Fallos de auth (API key inválida, no autorizado)
  • Errores de configuración o validación
  • Otros errores no transitorios

Comportamiento predeterminado (sin configuración)

Tareas únicas (schedule.kind: "at"):

  • En error transitorio: reintentar hasta 3 veces con backoff exponencial (30s → 1m → 5m).
  • En error permanente: deshabilitar inmediatamente.
  • En éxito u omisión: deshabilitar (o eliminar si deleteAfterRun: true).

Tareas recurrentes (cron / every):

  • En cualquier error: aplicar backoff exponencial (30s → 1m → 5m → 15m → 60m) antes de la próxima ejecución programada.
  • La tarea permanece habilitada; el backoff se reinicia después de la próxima ejecución exitosa.

Configura cron.retry para sobreescribir estos valores predeterminados (consulta Configuración).

Configuración

{
  cron: {
    enabled: true, // por defecto true
    store: "~/.openclaw/cron/jobs.json",
    maxConcurrentRuns: 1, // por defecto 1
    // Opcional: sobreescribir política de reintentos para tareas únicas
    retry: {
      maxAttempts: 3,
      backoffMs: [60000, 120000, 300000],
      retryOn: ["rate_limit", "overloaded", "network", "server_error"],
    },
    webhook: "https://example.invalid/legacy", // respaldo deprecado para tareas almacenadas con notify:true
    webhookToken: "replace-with-dedicated-webhook-token", // token bearer opcional para modo webhook
    sessionRetention: "24h", // cadena de duración o false
    runLog: {
      maxBytes: "2mb", // por defecto 2_000_000 bytes
      keepLines: 2000, // por defecto 2000
    },
  },
}

Comportamiento de poda del log de ejecuciones:

  • cron.runLog.maxBytes: tamaño máximo del archivo de log de ejecuciones antes de podar.
  • cron.runLog.keepLines: al podar, conservar solo las N líneas más recientes.
  • Ambos aplican a los archivos cron/runs/<jobId>.jsonl.

Comportamiento del webhook:

  • Preferido: configura delivery.mode: "webhook" con delivery.to: "https://..." por tarea.
  • Las URLs de webhook deben ser URLs http:// o https:// válidas.
  • Al publicar, el payload es el JSON del evento cron finalizado.
  • Si cron.webhookToken está configurado, el header de auth es Authorization: Bearer <cron.webhookToken>.
  • Si cron.webhookToken no está configurado, no se envía header Authorization.
  • Respaldo deprecado: las tareas legacy almacenadas con notify: true aún usan cron.webhook cuando está presente.

Deshabilitar cron completamente:

  • cron.enabled: false (configuración)
  • OPENCLAW_SKIP_CRON=1 (env)

Mantenimiento

Cron tiene dos rutas de mantenimiento integradas: retención de sesiones de ejecución aisladas y poda del log de ejecuciones.

Valores predeterminados

  • cron.sessionRetention: 24h (configura false para deshabilitar la poda de sesiones de ejecución)
  • cron.runLog.maxBytes: 2_000_000 bytes
  • cron.runLog.keepLines: 2000

Cómo funciona

  • Las ejecuciones aisladas crean entradas de sesión (...:cron:<jobId>:run:<uuid>) y archivos de transcripción.
  • El reaper elimina las entradas de sesión de ejecución expiradas más antiguas que cron.sessionRetention.
  • Para sesiones de ejecución eliminadas que ya no están referenciadas por el almacén de sesiones, OpenClaw archiva archivos de transcripción y purga archivos archivados antiguos eliminados en la misma ventana de retención.
  • Después de cada escritura de ejecución, se verifica el tamaño de cron/runs/<jobId>.jsonl:
    • si el tamaño del archivo excede runLog.maxBytes, se recorta a las runLog.keepLines líneas más recientes.

Advertencia de rendimiento para programadores de alto volumen

Las configuraciones de cron de alta frecuencia pueden generar grandes huellas de sesiones de ejecución y logs de ejecución. El mantenimiento es integrado, pero límites holgados aún pueden crear IO y trabajo de limpieza evitables.

Qué vigilar:

  • ventanas de cron.sessionRetention largas con muchas ejecuciones aisladas
  • cron.runLog.keepLines alto combinado con runLog.maxBytes grande
  • muchas tareas recurrentes ruidosas escribiendo al mismo cron/runs/<jobId>.jsonl

Qué hacer:

  • mantén cron.sessionRetention tan corto como tus necesidades de depuración/auditoría permitan
  • mantén los logs de ejecución acotados con runLog.maxBytes y runLog.keepLines moderados
  • mueve tareas de fondo ruidosas a modo aislado con reglas de entrega que eviten chatter innecesario
  • revisa el crecimiento periódicamente con openclaw cron runs y ajusta la retención antes de que los logs crezcan

Ejemplos de personalización

Conservar sesiones de ejecución por una semana y permitir logs de ejecución más grandes:

{
  cron: {
    sessionRetention: "7d",
    runLog: {
      maxBytes: "10mb",
      keepLines: 5000,
    },
  },
}

Deshabilitar la poda de sesiones de ejecución aisladas pero mantener la poda del log de ejecuciones:

{
  cron: {
    sessionRetention: false,
    runLog: {
      maxBytes: "5mb",
      keepLines: 3000,
    },
  },
}

Ajustar para uso de cron de alto volumen (ejemplo):

{
  cron: {
    sessionRetention: "12h",
    runLog: {
      maxBytes: "3mb",
      keepLines: 1500,
    },
  },
}

Inicio rápido CLI

Recordatorio único (ISO UTC, auto-eliminación después del éxito):

openclaw cron add \
  --name "Send reminder" \
  --at "2026-01-12T18:00:00Z" \
  --session main \
  --system-event "Reminder: submit expense report." \
  --wake now \
  --delete-after-run

Recordatorio único (sesión principal, despertar inmediato):

openclaw cron add \
  --name "Calendar check" \
  --at "20m" \
  --session main \
  --system-event "Next heartbeat: check calendar." \
  --wake now

Tarea aislada recurrente (announce a WhatsApp):

openclaw cron add \
  --name "Morning status" \
  --cron "0 7 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize inbox + calendar for today." \
  --announce \
  --channel whatsapp \
  --to "+15551234567"

Tarea cron recurrente con desfase explícito de 30 segundos:

openclaw cron add \
  --name "Minute watcher" \
  --cron "0 * * * * *" \
  --tz "UTC" \
  --stagger 30s \
  --session isolated \
  --message "Run minute watcher checks." \
  --announce

Tarea aislada recurrente (entrega a un tema de Telegram):

openclaw cron add \
  --name "Nightly summary (topic)" \
  --cron "0 22 * * *" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Summarize today; send to the nightly topic." \
  --announce \
  --channel telegram \
  --to "-1001234567890:topic:123"

Tarea aislada con sobreescritura de modelo y razonamiento:

openclaw cron add \
  --name "Deep analysis" \
  --cron "0 6 * * 1" \
  --tz "America/Los_Angeles" \
  --session isolated \
  --message "Weekly deep analysis of project progress." \
  --model "opus" \
  --thinking high \
  --announce \
  --channel whatsapp \
  --to "+15551234567"

Selección de agente (configuraciones multi-agente):

# Fijar una tarea al agente "ops" (recurre al predeterminado si ese agente no existe)
openclaw cron add --name "Ops sweep" --cron "0 6 * * *" --session isolated --message "Check ops queue" --agent ops

# Cambiar o limpiar el agente en una tarea existente
openclaw cron edit <jobId> --agent ops
openclaw cron edit <jobId> --clear-agent

Ejecución manual (force es el predeterminado, usa --due para ejecutar solo cuando corresponde):

openclaw cron run <jobId>
openclaw cron run <jobId> --due

cron.run ahora confirma una vez que la ejecución manual está en cola, no después de que la tarea termine. Las respuestas exitosas de cola se ven como { ok: true, enqueued: true, runId }. Si la tarea ya se está ejecutando o --due no encuentra nada pendiente, la respuesta se mantiene como { ok: true, ran: false, reason }. Usa openclaw cron runs --id <jobId> o el método cron.runs del gateway para inspeccionar la entrada finalizada.

Editar una tarea existente (parchear campos):

openclaw cron edit <jobId> \
  --message "Updated prompt" \
  --model "opus" \
  --thinking low

Forzar que una tarea cron existente se ejecute exactamente según horario (sin desfase):

openclaw cron edit <jobId> --exact

Historial de ejecuciones:

openclaw cron runs --id <jobId> --limit 50

Evento del sistema inmediato sin crear una tarea:

openclaw system event --mode now --text "Next heartbeat: check battery."

Superficie de API del Gateway

  • cron.list, cron.status, cron.add, cron.update, cron.remove
  • cron.run (force o due), cron.runs Para eventos del sistema inmediatos sin una tarea, usa openclaw system event.

Solución de problemas

”Nada se ejecuta”

  • Verifica que cron esté habilitado: cron.enabled y OPENCLAW_SKIP_CRON.
  • Verifica que el Gateway esté ejecutándose continuamente (cron se ejecuta dentro del proceso del Gateway).
  • Para horarios cron: confirma la zona horaria (--tz) vs la zona horaria del host.

Una tarea recurrente sigue retrasándose después de fallos

  • OpenClaw aplica backoff exponencial de reintentos para tareas recurrentes después de errores consecutivos: 30s, 1m, 5m, 15m, luego 60m entre reintentos.
  • El backoff se reinicia automáticamente después de la próxima ejecución exitosa.
  • Las tareas únicas (at) reintentan errores transitorios (límite de tasa, sobrecarga, red, error_servidor) hasta 3 veces con backoff; los errores permanentes deshabilitan inmediatamente. Consulta Política de reintentos.

Telegram entrega al lugar equivocado

  • Para temas de foro, usa -100…:topic:<id> para que sea explícito y sin ambigüedad.
  • Si ves prefijos telegram:... en logs o destinos almacenados de “última ruta”, eso es normal; la entrega cron los acepta y aún analiza los IDs de tema correctamente.

Reintentos de entrega announce de subagente

  • Cuando una ejecución de subagente se completa, el gateway anuncia el resultado a la sesión solicitante.
  • Si el flujo de announce devuelve false (por ejemplo, la sesión solicitante está ocupada), el gateway reintenta hasta 3 veces con seguimiento vía announceRetryCount.
  • Los announces más antiguos de 5 minutos después de endedAt se expiran forzosamente para prevenir que entradas obsoletas se repitan indefinidamente.
  • Si ves entregas announce repetidas en los logs, verifica el registro de subagentes por entradas con valores altos de announceRetryCount.