#10120: fix(cron): ensure next run is strictly in the future (#10035)
stale
Cluster:
Cron Job Enhancements
Croner library has a rare edge case where `nextRun()` can return a
timestamp in the past due to timezone/Intl boundary issues.
This can happen when:
- Timezone boundaries cross day boundaries in unexpected ways
- Intl.DateTimeFormat implementations have edge case bugs
- The computed next run falls exactly on or before `nowMs`
Fix: Added defensive check that if `next` is in the past or exactly now,
force it to look forward from the next day (+24 hours).
Test case added for the exact scenario from #10035:
- Current time: 2026-02-06 08:20 Shanghai (00:20 UTC)
- Daily job at 07:30 Shanghai
- Expected: Feb 7 07:30 Shanghai = Feb 6 23:30 UTC
---
🤖 AI-assisted PR
- Degree of testing: Fully tested (all 5 tests passing)
- Tool: OpenClaw agent with manual verification
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates cron scheduling to defensively handle a Croner edge case where `nextRun()` can return a timestamp at or before `nowMs`, by re-running `nextRun()` from a later base time. It also adds a regression test for the reported Asia/Shanghai daily schedule scenario and extends Oxlint’s ignore patterns.
The change is localized to `src/cron/schedule.ts` (used by the cron service’s next-run computation) and aims to prevent tight loops / immediate re-scheduling when Croner returns a non-future date.
<h3>Confidence Score: 4/5</h3>
- Mostly safe to merge once the DST-sensitive fallback is corrected.
- Changes are small and well-scoped, but the current +24h fallback can produce incorrect next-run times in DST-observing timezones because 24h != “next local day”.
- src/cron/schedule.ts
<!-- greptile_other_comments_section -->
**Context used:**
- Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8))
- Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13))
<!-- /greptile_comment -->
Most Similar PRs
#12303: fix(cron): correct nextRunAtMs calculation and prevent timer stall
by colddonkey · 2026-02-09
88.7%
#12443: fix(cron): don't advance past-due jobs that haven't been executed
by rummangeminicode · 2026-02-09
85.6%
#9684: fix: cron race condition - run due jobs before recomputing nextRunA...
by divol89 · 2026-02-05
83.5%
#11813: fix(cron): ensure 'at' schedule type correctly registers nextWakeAt...
by leo-reifying · 2026-02-08
82.7%
#13796: fix: skip recomputing nextRunAtMs for running cron jobs (#13739)
by echoVic · 2026-02-11
82.3%
#14667: fix: preserve missed cron runs when updating job schedule
by WalterSumbon · 2026-02-12
82.0%
#5428: fix(Cron): prevent one-shot loop on skip
by imshrishk · 2026-01-31
81.9%
#9060: Fix: Preserve scheduled cron jobs after gateway restart
by vishaltandale00 · 2026-02-04
81.8%
#12982: fix(cron): prevent status/list from advancing overdue job nextRunAtMs
by hclsys · 2026-02-10
81.6%
#12747: fix: catch up missed cron-expression job runs on restart
by obin94-commits · 2026-02-09
80.8%