← Back to PRs

#8034: fix(cron): run past-due one-shot jobs immediately on startup

by FelixFoster open 2026-02-03 13:55 View on GitHub →
stale
Fixes #8016. ## The Problem When the gateway restarts, any one-shot cron jobs (schedule kind at) that were scheduled for a time *during* the downtime (or before the restart completed) were being ignored. They would sit in the database with enabled: true but never run. ## The Fix 1. Updated `armTimer` in `timer.ts` to handle `nextWakeAtMs` values that are in the past. Instead of potentially failing or setting an invalid timeout, it now clamps the delay to `0`, forcing immediate execution on the next tick. 2. Verified `computeJobNextRunAtMs` continues to return the original `atMs` for incomplete jobs, ensuring they remain 'due'. ## Verification - Created a one-shot job scheduled for 2 minutes in the future. - Stopped the gateway. - Waited 5 minutes (so the job is now past due). - Restarted the gateway. - **Result:** The job now executes immediately upon startup. <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR fixes missed one-shot (`schedule.kind === "at"`) cron executions after gateway restarts by changing `armTimer` to treat “past-due” wake times as an immediate tick: it now clamps negative delays to `0` and avoids the prior `if (!nextAt)` early-return that could accidentally skip scheduling when `nextWakeAtMs` was `0`. `computeJobNextRunAtMs` behavior for one-shot jobs remains effectively the same (it returns `schedule.atMs` until a successful run), so overdue jobs stay due; the key behavioral change is the timer arming logic that now handles past timestamps safely. <h3>Confidence Score: 4/5</h3> - This PR is largely safe to merge and addresses the missed one-shot scheduling bug with a small, well-scoped change. - The change is minimal and targeted (timer arming logic), and it preserves existing next-run calculations for one-shot jobs. Main remaining concern is that `armTimer` now accepts any `number` including `NaN`, which could lead to unexpected immediate ticks if state is corrupted; otherwise behavior looks consistent. - src/cron/service/timer.ts (guarding against NaN/invalid nextAt); src/cron/service/jobs.ts (comment accuracy). <!-- greptile_other_comments_section --> <sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub> <!-- /greptile_comment -->

Most Similar PRs