{"record":{"id":"cde13ed0c2aa214c","repo":"influxdata/influxdb","slug":"can-t-be-out-of-range","errorCode":null,"errorMessage":"can't be out of range","messagePattern":"can't be out of range","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"influxdb3_processing_engine/src/plugins.rs","lineNumber":211,"sourceCode":"        }\n    }\n\n    fn new_cron(cron_schedule: CronSchedule, time_provider: Arc<dyn TimeProvider>) -> Self {\n        let mut schedule = Box::new(cron_schedule.after_owned(time_provider.now().date_time()));\n        let next_trigger_time = schedule.next();\n        Self {\n            schedule: Schedule::Cron(schedule),\n            next_trigger_time,\n        }\n    }\n\n    fn new_every(duration: Duration, time_provider: Arc<dyn TimeProvider>) -> Self {\n        let now = time_provider.now().date_time();\n        let duration_millis = duration.num_milliseconds();\n        let now_millis = now.timestamp_millis();\n        let next_trigger_millis = ((now_millis / duration_millis) + 1) * duration_millis;\n        let next_trigger_time = Some(\n            DateTime::from_timestamp_millis(next_trigger_millis).expect(\"can't be out of range\"),\n        );\n        Self {\n            schedule: Schedule::Every(duration),\n            next_trigger_time,\n        }\n    }\n\n    fn advance_time(&mut self) {\n        self.next_trigger_time = match &mut self.schedule {\n            Schedule::Cron(schedule) => schedule.next(),\n            Schedule::Every(duration) => self.next_trigger_time.map(|time| time + *duration),\n        };\n    }\n\n    /// A funky little method to get a tokio Instant that we can call `tokio::time::sleep_until()` on.\n    fn next_run_time(&self) -> Option<Time> {\n        let next_trigger_time = Time::from_datetime(*self.next_trigger_time.as_ref()?);\n        Some(next_trigger_time)","sourceCodeStart":193,"sourceCodeEnd":229,"githubUrl":"https://github.com/influxdata/influxdb/blob/06200ef96ba82c5f6727e5038a83af8e722c6875/influxdb3_processing_engine/src/plugins.rs#L193-L229","documentation":"This is a panic, not a returned error: `new_every` computes the next trigger time by rounding `now` up to the next multiple of the duration, then calls `DateTime::from_timestamp_millis(...).expect(\"can't be out of range\")`. The expect fires only if the computed millisecond timestamp falls outside chrono's representable range — practically only via overflow with extreme durations or a broken time provider.","triggerScenarios":"Calling `Schedule::new_every` (via `try_new` on an `Every` spec) when `(now_millis / duration_millis + 1) * duration_millis` overflows i64 milliseconds, or when the time provider returns a timestamp near i64::MAX — even though durations > 1 year are pre-filtered by the try_new check.","commonSituations":"A custom/mock TimeProvider returning huge or negative timestamps; a duration that passes the 1-year check but still overflows on multiplication; running with a corrupted system clock far in the future.","solutions":["Verify the duration passed is at most 1 year (the try_new guard) — avoid constructing `new_every` directly with unvalidated durations.","Fix or replace the TimeProvider mock so `now()` returns a realistic timestamp.","If you control the code, replace `.expect` with a fallible conversion that returns an error instead of panicking.","Correct the host system clock if it is wildly wrong."],"exampleFix":"// before\nlet next_trigger_time = DateTime::from_timestamp_millis(next_trigger_millis).expect(\"can't be out of range\");\n// after\nlet next_trigger_time = DateTime::from_timestamp_millis(next_trigger_millis)\n    .context(\"computed next trigger timestamp out of range\")?;","handlingStrategy":"validation","validationCode":"// Guard inputs before constructing the schedule\nassert!(duration > Duration::zero() && duration <= parse_duration(\"1 year\").unwrap());\nlet now_millis = time_provider.now().date_time().timestamp_millis();\nassert!(now_millis > 0 && now_millis < i64::MAX / 2, \"implausible clock value\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never bypass try_new to call new_every directly with unvalidated durations","Sanity-check custom/mock TimeProvider values in tests","Monitor host clock sync (NTP) on servers running triggers"],"tags":["panic","scheduling","overflow","datetime"],"backgroundTag":"argument-out-of-range","analyzedSha":"06200ef96ba82c5f6727e5038a83af8e722c6875","analyzedAt":"2026-09-19T12:55:30.003Z","contentChangedAt":"2026-09-19T12:55:30.003Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}