Skip to content

Cron scheduler bug: missed runs cause permanent stall #8424

@tssandor

Description

@tssandor

Bug Summary

The cron schedule type has a critical bug where missed scheduled runs cause the job to get permanently stuck on a past timestamp, never recovering.

Symptoms

  • cron status shows nextWakeAtMs in the past
  • Job doesn't run even though it's enabled and shows ok status
  • Restarting the gateway reloads the stale timestamp — doesn't recalculate from current time

Root Cause

The scheduler calculates nextRunAtMs from lastRunAtMs instead of max(lastRunAtMs, currentTime). When runs are missed (gateway down, system asleep), the missed timestamps accumulate and the scheduler never catches up.

Reproduction Steps

  1. Create a job with "schedule": {"kind": "cron", "expr": "0 */4 * * *"}
  2. Let it run successfully once (e.g., at midnight)
  3. Have the gateway miss the next scheduled runs (04:00, 08:00)
  4. Check cron status — it shows nextWakeAtMs still at 04:00 (in the past)
  5. Restart gateway — still stuck on 04:00

Expected Behavior

On startup or when evaluating schedules, the scheduler should check if nextRunAtMs is in the past and recalculate from the current time.

Workaround

Use schedule.kind: "every" instead of "cron":

// ❌ Gets stuck if runs are missed
"schedule": { "kind": "cron", "expr": "0 */4 * * *" }

// ✅ Calculates from current time
"schedule": { "kind": "every", "everyMs": 14400000 }

Environment

  • OpenClaw version: (gateway restarted today, 2026-02-04)
  • OS: macOS Darwin 25.0.0 (arm64)
  • Node: v25.5.0

Suggested Fix

In the scheduler logic, when loading jobs or on heartbeat evaluation:

if (job.state.nextRunAtMs < Date.now()) {
  // Recalculate next occurrence from now, not from lastRunAtMs
  job.state.nextRunAtMs = calculateNextFromCurrentTime(job.schedule);
}

This ensures missed runs don't permanently stall the scheduler.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions