Skip to main content

Automation troubleshooting

Use this page for scheduler and delivery issues (cron + heartbeat).

Command ladder

Then run automation checks:

Cron not firing

Good output looks like:
  • cron status reports enabled and a future nextWakeAtMs.
  • Job is enabled and has a valid schedule/timezone.
  • cron runs shows ok or explicit skip reason.
Common signatures:
  • cron: scheduler disabled; jobs will not run automatically → cron disabled in config/env.
  • cron: timer tick failed → scheduler tick crashed; inspect surrounding stack/log context.
  • reason: not-due in run output → openclaw cron run <jobId> --due or Web UI Run if due was used and the job is not due yet.
  • main job requires payload.kind="systemEvent" → the job is stored as a main-session job with an incompatible payload. Use the Web UI Timeline message or Check first, then nudge job type, or recreate the job with a matching sessionTarget/payload.kind.
  • isolated job requires payload.kind=agentTurn → the job is stored as an isolated job without an assistant-task payload. Use the Web UI Assistant task job type or recreate the job with --session isolated --message ....
  • wake-gate-empty → the wake-gate check ran and found no work. This is a valid skipped result, not a scheduler failure.
  • already running or already-running → the previous run or target lane is still active. Wait for it to finish, then inspect openclaw cron runs --id <jobId> --limit 20.

Cron fired but no delivery

Good output looks like:
  • Run status is ok.
  • Delivery mode/target are set for isolated jobs.
  • Channel probe reports target channel connected.
Common signatures:
  • Run succeeded but delivery mode is none → no external message is expected.
  • Delivery target missing/invalid (channel/to) → run may succeed internally but skip outbound.
  • Channel auth errors (unauthorized, missing_scope, Forbidden) → delivery blocked by channel credentials/permissions.
  • Web UI shows Not delivered on an internal run → delivery was not requested. Set result delivery to announce or webhook when you expect an outbound message.

Heartbeat suppressed or skipped

Good output looks like:
  • Heartbeat enabled with non-zero interval.
  • Last heartbeat result is ran (or skip reason is understood).
Common signatures:
  • heartbeat skipped with reason=quiet-hours → outside activeHours.
  • requests-in-flight → main lane busy; heartbeat deferred.
  • empty-heartbeat-file → interval heartbeat skipped because HEARTBEAT.md has no actionable content and no tagged cron event is queued.
  • alerts-disabled → visibility settings suppress outbound heartbeat messages.

Timezone and activeHours gotchas

Quick rules:
  • Config path not found: agents.defaults.userTimezone means the key is unset; heartbeat falls back to host timezone (or activeHours.timezone if set).
  • Cron without --tz uses gateway host timezone.
  • Heartbeat activeHours uses configured timezone resolution (user, local, or explicit IANA tz).
  • ISO timestamps without timezone are treated as UTC for cron at schedules.
Common signatures:
  • Jobs run at the wrong wall-clock time after host timezone changes.
  • Heartbeat always skipped during your daytime because activeHours.timezone is wrong.
Related: