{"record":{"id":"771cd98c7e633a3a","repo":"nautechsystems/nautilus_trader","slug":"interval-exceeds-u64-nanoseconds","errorCode":null,"errorMessage":"Interval exceeds u64 nanoseconds","messagePattern":"Interval exceeds u64 nanoseconds","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/common/src/clock.rs","lineNumber":710,"sourceCode":"}\n\ntype SetTimeAlertNsHandler<'a> =\n    dyn Fn(&str, UnixNanos, Option<TimeEventCallback>, Option<bool>) -> anyhow::Result<()> + 'a;\ntype NextTimeNsHandler<'a> = dyn Fn(&str) -> Option<UnixNanos> + 'a;\ntype SetTimerNsHandler<'a> = dyn Fn(\n        &str,\n        DurationNanos,\n        Option<UnixNanos>,\n        Option<UnixNanos>,\n        Option<TimeEventCallback>,\n        Option<bool>,\n        Option<bool>,\n    ) -> anyhow::Result<()>\n    + 'a;\n\nfn duration_to_nanos(duration: Duration) -> anyhow::Result<DurationNanos> {\n    DurationNanos::try_from(duration)\n        .map_err(|_| anyhow::anyhow!(\"Interval exceeds u64 nanoseconds\"))\n}\n\n/// Registry for timer event callbacks.\n///\n/// Provides shared callback registration and retrieval logic used by both\n/// `TestClock` and `LiveClock`.\n#[derive(Debug, Default)]\npub struct CallbackRegistry {\n    default_callback: Option<TimeEventCallback>,\n    callbacks: AHashMap<Ustr, TimeEventCallback>,\n}\n\nimpl CallbackRegistry {\n    /// Creates an empty callback registry.\n    #[must_use]\n    pub fn new() -> Self {\n        Self::default()\n    }","sourceCodeStart":692,"sourceCodeEnd":728,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/clock.rs#L692-L728","documentation":"duration_to_nanos converts a std Duration into a DurationNanos (u64 nanoseconds). Durations longer than u64::MAX nanoseconds (~584 years) cannot be represented, so TryFrom fails and the function returns 'Interval exceeds u64 nanoseconds'. It is used by set_timer for timer intervals.","triggerScenarios":"Calling set_timer (on TestClock or LiveClock) with a Duration whose nanosecond count exceeds u64::MAX — e.g. programmatically built durations like Duration::from_secs(u64::MAX) or huge multiplier arithmetic that overflows the nanosecond range.","commonSituations":"Config parsers computing timer intervals with overflow (seconds * 1e9 in a wider type then converting); sentinel 'infinite' timeouts encoded as enormous durations; fuzz/property tests generating extreme Duration values.","solutions":["Clamp or validate the interval before calling set_timer (e.g. cap at a sane maximum like Duration::from_secs(u64::MAX / 1_000_000_000)).","Fix the interval computation so it cannot overflow — compute in u128 or use checked_mul when converting seconds/millis to nanoseconds.","If 'never fire' semantics are needed, model it explicitly (no timer) rather than passing a gigantic Duration.","Propagate the anyhow error from set_timer and surface a clear configuration message instead of panicking."],"exampleFix":"// before\nlet interval = Duration::from_secs(years * 365 * 24 * 3600);\nclock.set_timer(name, callback, start, interval)?; // may overflow u64 ns\n\n// after\nlet interval = Duration::from_secs(\n    (years as u128 * 365 * 24 * 3600).min(u64::MAX as u128 / 1_000_000_000) as u64,\n);\nclock.set_timer(name, callback, start, interval)?;","handlingStrategy":"validation","validationCode":"# Rust\nconst MAX_INTERVAL: Duration = Duration::from_secs(u64::MAX / 1_000_000_000);\nfn validate_interval(d: Duration) -> anyhow::Result<()> {\n    anyhow::ensure!(d <= MAX_INTERVAL, \"interval {d:?} exceeds u64 nanoseconds\");\n    Ok(())\n}","typeGuard":"fn fits_u64_nanos(d: Duration) -> bool {\n    d.as_secs() <= u64::MAX / 1_000_000_000\n}","tryCatchPattern":"match clock.set_timer(name, callback, start, interval) {\n    Ok(()) => {},\n    Err(e) if e.to_string().contains(\"exceeds u64 nanoseconds\") => {\n        tracing::error!(\"timer interval too large: {e}; clamping\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Compute durations with checked arithmetic (checked_mul) when converting from seconds/millis to nanos.","Cap configured timer intervals to a sane maximum in config validation.","Represent 'infinite/never' timeouts explicitly instead of giant Duration values."],"tags":["clock","timer","duration","overflow"],"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-14T05:17:10.506Z"}