{"record":{"id":"5beba2c0d7a205a3","repo":"nautechsystems/nautilus_trader","slug":"cannot-increment-time-beyond-u64-max","errorCode":null,"errorMessage":"Cannot increment time beyond u64::MAX","messagePattern":"Cannot increment time beyond u64::MAX","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/time.rs","lineNumber":293,"sourceCode":"    /// The mode check is not atomic with the subsequent update. If another thread calls\n    /// `make_realtime()` between the check and update, the invariant can be violated.\n    /// This is intentional: mode switching is a setup-time operation and should not\n    /// occur concurrently with time operations. Callers must ensure mode switches are\n    /// complete before resuming time operations.\n    pub fn increment_time(&self, delta: DurationNanos) -> anyhow::Result<UnixNanos> {\n        anyhow::ensure!(\n            !self.realtime.load(Ordering::SeqCst),\n            \"Cannot increment time while clock is in realtime mode\"\n        );\n\n        let previous =\n            match self\n                .timestamp_ns\n                .try_update(Ordering::AcqRel, Ordering::Acquire, |current| {\n                    current.checked_add(delta.as_u64())\n                }) {\n                Ok(prev) => prev,\n                Err(_) => anyhow::bail!(\"Cannot increment time beyond u64::MAX\"),\n            };\n\n        debug_assert!(\n            !self.realtime.load(Ordering::SeqCst),\n            \"Invariant: clock must remain in static mode across `increment_time`\"\n        );\n\n        Ok(UnixNanos::from(previous) + delta)\n    }\n\n    /// Retrieves and updates the current \"real-time\" clock, returning a strictly increasing\n    /// timestamp based on system time.\n    ///\n    /// Internally:\n    /// - We fetch `now` from [`SystemTime::now()`].\n    /// - We do an atomic compare-and-exchange (using [`Ordering::AcqRel`]) to ensure the stored\n    ///   timestamp is never less than the last timestamp.\n    ///","sourceCodeStart":275,"sourceCodeEnd":311,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/time.rs#L275-L311","documentation":"`increment_time` on the static/test clock advances the internal `timestamp_ns` (an atomic u64) by the given delta using checked addition. When the addition would overflow u64::MAX, the CAS update fails and the method bails with this error instead of silently wrapping time. It preserves the invariant that the simulated clock is monotonically increasing and never wraps.","triggerScenarios":"Calling `increment_time` with a delta such that current_ns + delta > u64::MAX (≈1.8e19 ns). In practice: repeatedly advancing a long-running static clock by huge deltas, or one call with an astronomically large `TimeDelta`/nanosecond value.","commonSituations":"Backtests that add many large increments to a clock initialized near u64::MAX; unit tests or fuzzers that pass u64::MAX deltas; miscomputed deltas (nanoseconds vs seconds confusion producing enormous values).","solutions":["Reduce the size or number of increments so the accumulated time stays far below u64::MAX","Reinitialize the static clock to a smaller starting timestamp","Use the realtime clock if you need wall-clock time rather than arbitrary increments","Catch the error and treat it as end-of-simulation in test harnesses"],"exampleFix":"// before\nclock.increment_time(TimeDelta::from_nanos(u64::MAX))?; // overflows\n// after\nlet delta = TimeDelta::from_secs(1);\nif clock.timestamp_ns() > u64::MAX - delta.as_u64() {\n    // stop or reset the clock before incrementing\n} else {\n    clock.increment_time(delta)?;\n}","handlingStrategy":"try-catch","validationCode":"let delta_u64 = delta.as_u64();\nif clock.timestamp_ns() > u64::MAX - delta_u64 {\n    // skip, reset clock, or end simulation\n}","typeGuard":"fn can_increment(current_ns: u64, delta_ns: u64) -> bool {\n    current_ns.checked_add(delta_ns).is_some()\n}","tryCatchPattern":"match clock.increment_time(delta) {\n    Ok(prev) => /* continue */,\n    Err(e) => tracing::warn!(\"clock exhausted: {e}\"), // end-of-simulation handling\n}","preventionTips":["Start static clocks at realistic small timestamps","Bound total simulated advance in long backtests","Sanity-check delta magnitudes (ns vs s confusion)"],"tags":["rust","time","overflow","testing"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}