From 18c62667e7f4a73ce85855e5ea4a019f4370350a Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Thu, 27 Nov 2025 13:35:55 +0100 Subject: [PATCH] fix(scheduler): iterate over copy when handling time backwards The time-backwards handling code iterates over entries while calling Update(), which reorders the heap via heap.Fix(). This could cause entries to be visited twice or skipped. Fix by iterating over a copy of the entries slice, ensuring all entries are checked exactly once regardless of heap reordering. Fixes #40 --- cron.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cron.go b/cron.go index 64a922ab..1a194048 100644 --- a/cron.go +++ b/cron.go @@ -274,7 +274,10 @@ func (c *Cron) run() { // Handle system time moving backwards (NTP correction, VM snapshot restore). // If Prev is in the future relative to now, time moved backwards. - for _, e := range c.entries { + // Iterate over a copy since Update() reorders the heap. + entriesCopy := make([]*Entry, len(c.entries)) + copy(entriesCopy, c.entries) + for _, e := range entriesCopy { if !e.Prev.IsZero() && e.Prev.After(now) { e.Next = e.Schedule.Next(now) c.entries.Update(e)