#8811: fix(cron): handle atMs fallback for kind=at jobs
stale
Cluster:
Cron Enhancements and Fixes
Fixes issue #8734.
Tool-created cron jobs with `kind=at` were failing to fire because `nextRunAtMs` was missing in the job state. This was due to `computeJobNextRunAtMs` only checking `job.schedule.at` and not falling back to `atMs` (which the tool and CLI sometimes provide before normalization).
Changes:
- Updated `computeJobNextRunAtMs` to handle `atMs` fallback.
- Improved `coerceSchedule` in normalization to better handle numeric `at` values and cleanup.
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes one-shot cron jobs (`schedule.kind="at"`) created by tooling that sometimes send `atMs` before normalization. It updates `computeJobNextRunAtMs` to fall back to `schedule.atMs` when `schedule.at` isn’t present, and it improves schedule normalization so numeric `schedule.at` values are coerced to an ISO timestamp and `atMs` is cleaned up when the job is determined to be an `at` schedule.
Overall, the change fits into the cron subsystem’s existing split between input normalization (`src/cron/normalize.ts`) and runtime scheduling (`src/cron/service/jobs.ts` / `src/cron/schedule.ts`) by making the scheduler resilient to pre-normalized/legacy shapes coming from the CLI/tooling.
<h3>Confidence Score: 3/5</h3>
- This PR is likely safe to merge, but there’s a behavioral edge case around scheduling past `kind="at"` timestamps that’s worth confirming.
- Changes are localized and align with the stated bug fix (fallback to `atMs` plus better normalization). The main remaining concern is `computeJobNextRunAtMs` now bypasses the `> nowMs` check used in `computeNextRunAtMs` for `kind="at"`, which could cause immediate execution for past timestamps (depending on intended semantics). Tooling/CI couldn’t be run in this environment (no node/pnpm), so confidence is moderated.
- src/cron/service/jobs.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
**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
#11813: fix(cron): ensure 'at' schedule type correctly registers nextWakeAt...
by leo-reifying · 2026-02-08
88.9%
#9670: fix: handle numeric string timestamps in cron schedule normalizatio...
by divol89 · 2026-02-05
87.1%
#12303: fix(cron): correct nextRunAtMs calculation and prevent timer stall
by colddonkey · 2026-02-09
86.0%
#5624: add support_human_readable_time_format in cron
by simran122 · 2026-01-31
85.2%
#5428: fix(Cron): prevent one-shot loop on skip
by imshrishk · 2026-01-31
84.3%
#12443: fix(cron): don't advance past-due jobs that haven't been executed
by rummangeminicode · 2026-02-09
84.1%
#9088: fix(cron): ensure nextRunAtMs is computed when enabled is undefined...
by divol89 · 2026-02-04
84.1%
#9684: fix: cron race condition - run due jobs before recomputing nextRunA...
by divol89 · 2026-02-05
81.8%
#15875: fix(cron): normalize seconds to milliseconds in timestamps
by Shuai-DaiDai · 2026-02-14
81.5%
#12747: fix: catch up missed cron-expression job runs on restart
by obin94-commits · 2026-02-09
81.3%