openclaw - ✅(Solved) Fix Cron scheduler produces incorrect nextRunAtMs for certain schedules (jumps to future dates) [1 pull requests, 1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#77867Fetched 2026-05-06 06:20:06
View on GitHub
Comments
1
Participants
2
Timeline
2
Reactions
2
Timeline (top)
commented ×1cross-referenced ×1

Fix Action

Fix / Workaround

Workaround: Manual correction in jobs-state.json for state.nextRunAtMs after each restart.

PR fix notes

PR #78272: fix(cron): repair stale future next-run slots

Description (problem / solution / changelog)

Summary

  • Problem: persisted cron nextRunAtMs values could remain in the future even when they no longer matched the stored cron schedule, causing timezone-aware daily jobs to appear jumped to stale future dates.
  • Why it matters: affected jobs stay delayed after restart/read paths instead of recovering to the next valid schedule slot.
  • What changed: cron maintenance now repairs only future cron timestamps that are invalid schedule slots and have leapt beyond adjacent natural occurrences.
  • What did NOT change (scope boundary): past-due slots, valid future slots, running jobs, and retry backoff slots remain preserved.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #77867
  • This PR fixes a bug or regression

Real behavior proof (required for external PRs)

  • Behavior or issue addressed: cron jobs with persisted stale future nextRunAtMs values no longer preserve invalid future slots.
  • Real environment tested: local OpenClaw repo integration workspace with a fresh Gateway on loopback port 64106.
  • Exact steps or command run after this patch: seeded an integration cron store with nextRunAtMs=2026-05-12T16:00:00.000Z, started the integration Gateway, and read openclaw cron list --all --json through the CLI.
  • Evidence after fix:
gateway_workspace=cron-next-run-gateway-fixed
gateway_port=64106
stale_future_preserved=false
FIXED_THROUGH_GATEWAY stale_future_preserved=false
  • Observed result after fix: the Gateway read path no longer preserves the stale future slot.
  • What was not tested: broad pnpm check:changed in Testbox; blacksmith was not installed locally.
  • Before evidence:
workspace=cron-next-run-repro
gateway_port=62845
fixed_now=2026-05-05T12:00:00.000Z
schedule=0 0 21 * * * Asia/Shanghai
expected_next=2026-05-05T13:00:00.000Z
actual_next=2026-05-12T16:00:00.000Z
BUG_REPRODUCED preserved_bad_future=true

Root Cause (if applicable)

  • Root cause: recomputeNextRunsForMaintenance() deliberately preserved all existing future nextRunAtMs values. That protected valid restart/retry state, but it also preserved stale future values that were no longer cron schedule occurrences.
  • Missing detection / guardrail: no maintenance-time validation checked whether a future cron timestamp still aligned with the effective staggered cron schedule.
  • Contributing context (if known): read/startup paths must not advance due jobs without execution, so the repair has to stay narrower than a full recompute.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/cron/service.jobs.test.ts
  • Scenario the test should lock in: repair an invalid future Asia/Shanghai cron slot while preserving valid future slots and retry backoff slots.
  • Why this is the smallest reliable guardrail: the bug is in scheduler state reconciliation before timer execution, so direct service-job maintenance coverage catches the contract without a channel/model run.
  • Existing test that already covers this (if any): none for invalid future cron slots.

User-visible / Behavior Changes

Timezone-aware cron jobs with stale persisted future nextRunAtMs values can recover to a valid next schedule slot during maintenance/read paths.

Diagram (if applicable)

Before:
cron store stale future nextRunAtMs -> list/startup maintenance -> stale value preserved

After:
cron store stale future nextRunAtMs -> schedule-slot validation -> recompute next valid slot

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No

Repro + Verification

Environment

  • OS: macOS local worktree
  • Runtime/container: Node 22 through repo pnpm test wrapper
  • Model/provider: N/A
  • Integration/channel (if any): repo-local integration Gateway on loopback
  • Relevant config (redacted): cron enabled in isolated integration workspace

Steps

  1. Seed a cron store with schedule 0 0 21 * * * in Asia/Shanghai and stale nextRunAtMs=2026-05-12T16:00:00.000Z.
  2. Read jobs through CronService.list() and the integration Gateway cron list path.
  3. Confirm the stale value is not preserved after the fix.

Expected

  • Invalid stale future nextRunAtMs is repaired to a valid future cron slot.

Actual

  • Fixed. The integration Gateway proof reports FIXED_THROUGH_GATEWAY stale_future_preserved=false.

Commands run

pnpm exec oxfmt --check --threads=1 src/cron/service/jobs.ts src/cron/service.jobs.test.ts
pnpm test src/cron/service.jobs.test.ts src/cron/service.restart-catchup.test.ts src/cron/service.issue-13992-regression.test.ts src/cron/service.issue-16156-list-skips-cron.test.ts
pnpm test src/cron/schedule.test.ts src/cron/service.issue-regressions.test.ts src/cron/service/timer.regression.test.ts src/cron/service.store-load-invalid-main-job.test.ts src/cron/store.test.ts
git diff --check

Changed files

  • CHANGELOG.md (modified, +1/-0)
  • src/cron/service.issue-13992-regression.test.ts (modified, +29/-0)
  • src/cron/service.jobs.test.ts (modified, +213/-0)
  • src/cron/service.restart-catchup.test.ts (modified, +54/-0)
  • src/cron/service/jobs.ts (modified, +113/-2)
  • src/cron/service/timer.ts (modified, +3/-2)
RAW_BUFFERClick to expand / collapse

Bug: Cron scheduler produces incorrect nextRunAtMs for certain schedules after restart

Description: After Gateway restart (or during runtime), the cron scheduler incorrectly calculates nextRunAtMs for certain jobs, jumping dates by weeks or months into the future instead of the next scheduled run.

Steps to Reproduce:

  1. Configure a cron job with schedule 0 0 21 * * * (daily at 21:00)
  2. Let the job run normally
  3. Restart the Gateway (or observe over time)
  4. The job's nextRunAtMs jumps to June instead of the next day's 21:00

Expected Behavior: nextRunAtMs should always be the next scheduled execution time based on the cron expression.

Actual Behavior: For certain cron expressions, nextRunAtMs jumps weeks/months in the future after Gateway restart.

Affected Jobs (observed on 2026-05-05):

JobScheduleExpected nextRunActual nextRun
每日系统巡检0 0 21 * * *2026-05-05 21:002026-05-13 00:00
Librarian 每日复盘0 0 22 * * *2026-05-05 22:002026-05-14 00:00
Cron 执行诊断巡检0 0 23 * * *2026-05-05 23:002026-05-15 00:00

Pattern:

  • 6-field cron expressions (* * * * * *) more affected
  • Simple daily schedules like 0 3 * * * work correctly
  • Bug appears on restart and during runtime
  • Memory Dreaming with 0 3 * * * always correct

Environment:

  • OpenClaw: latest (2026.05)
  • Node.js: v24.14.1
  • Host: Linux 6.17.0-22-generic
  • Timezone: Asia/Shanghai
  • Cron library: croner (per docs)

Workaround: Manual correction in jobs-state.json for state.nextRunAtMs after each restart.

extent analysis

TL;DR

The cron scheduler's incorrect calculation of nextRunAtMs after restart can be temporarily mitigated by manually correcting the state.nextRunAtMs in jobs-state.json after each restart.

Guidance

  • Verify that the cron library croner is correctly handling 6-field cron expressions, as the issue seems more prevalent with these expressions.
  • Check the system's timezone settings (Asia/Shanghai) to ensure it's correctly configured and not causing discrepancies in scheduling.
  • Test simpler cron expressions (like 0 3 * * *) to confirm they work as expected and identify any patterns in the failures.
  • Consider logging or monitoring the nextRunAtMs calculations to better understand when and why the incorrect jumps occur.

Example

No code snippet is provided as the issue is more related to configuration and library usage rather than a specific code error.

Notes

The provided workaround of manually correcting state.nextRunAtMs in jobs-state.json after each restart is temporary and not a permanent solution. The root cause, potentially related to the croner library or timezone settings, needs to be identified and addressed for a lasting fix.

Recommendation

Apply the workaround of manual correction in jobs-state.json after each restart until a more permanent solution can be found, as it provides a temporary mitigation to the scheduling issue.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - ✅(Solved) Fix Cron scheduler produces incorrect nextRunAtMs for certain schedules (jumps to future dates) [1 pull requests, 1 comments, 2 participants]