← Back to PRs

#17838: fix: prevent cron job spin loop by not recomputing nextRunAtMs for recently ran jobs

by MisterGuy420 open 2026-02-16 06:56 View on GitHub →
size: XS trusted-contributor
## Summary When cron jobs with sessionTarget: "isolated" and payload.kind: "agentTurn" execute, the nextRunAtMs can get set back to the same past timestamp due to recomputeNextRuns overwriting the correctly computed value. This causes an infinite spin loop where the scheduler repeatedly triggers the same job hundreds of times per second. ## Changes - Added a check in `recomputeNextRuns` to avoid recomputing nextRunAtMs when a job just ran (within the last second), preventing the infinite spin loop. ## Testing - All 118 cron-related tests pass - The fix adds a "justRan" check that considers a job as recently ran if lastRunAtMs was within the last 1000ms Fixes openclaw/openclaw#17821 <!-- greptile_comment --> <h3>Greptile Summary</h3> Adds a 1-second "just ran" guard to `recomputeNextRuns` to prevent a spin loop where `nextRunAtMs` gets overwritten back to a past-due timestamp after `applyJobResult` has already computed the correct future value. - The root cause is that for `every`-type schedules, `computeJobNextRunAtMs(job, now)` can return a past timestamp when `now` hasn't advanced past the next interval boundary. After `applyJobResult` correctly sets `nextRunAtMs` using `result.endedAt`, the subsequent `recomputeNextRuns` call overwrites it, causing an infinite re-trigger loop. - The fix is minimal and well-scoped: it checks `now - lastRunAtMs < 1000` to skip recomputation for jobs that just executed, preserving the correct `nextRunAtMs` already set by `applyJobResult`. - No regressions to other call sites (`start()`, `add()`, `run()`, `ensureLoaded`) since `applyJobResult` always leaves a valid `nextRunAtMs` for enabled recurring jobs, and newly created or long-idle jobs are unaffected by the guard. <h3>Confidence Score: 5/5</h3> - This PR is safe to merge — it's a small, targeted fix with a clear root cause and no regressions. - The change is minimal (3 new lines + 1 modified condition), correctly addresses a well-understood spin loop bug, and doesn't affect unrelated code paths. All call sites of `recomputeNextRuns` were verified: newly created jobs, startup recovery, and long-idle jobs are unaffected by the guard. The `applyJobResult` function always leaves a valid `nextRunAtMs` for enabled recurring jobs, so the guard safely preserves those values. - No files require special attention. <sub>Last reviewed commit: 52f3ef3</sub> <!-- greptile_other_comments_section --> <!-- /greptile_comment -->

Most Similar PRs