{"record":{"id":"76067ac9e45c895b","repo":"nautechsystems/nautilus_trader","slug":"durationnanos-overflow-in-from-mins","errorCode":null,"errorMessage":"DurationNanos overflow in from_mins","messagePattern":"DurationNanos overflow in from_mins","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":174,"sourceCode":"    /// Creates a duration from a number of whole seconds.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the result exceeds [`DurationNanos::MAX`].\n    pub const fn try_from_secs(secs: u64) -> Result<Self, DurationNanosOutOfRangeError> {\n        Self::try_from_units(secs, NANOSECONDS_IN_SECOND, \"seconds\")\n    }\n\n    /// Creates a duration from a number of whole minutes.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]\n    pub const fn from_mins(mins: u64) -> Self {\n        match Self::try_from_mins(mins) {\n            Ok(duration) => duration,\n            Err(_) => panic!(\"DurationNanos overflow in from_mins\"),\n        }\n    }\n\n    /// Creates a duration from a number of whole minutes.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the result exceeds [`DurationNanos::MAX`].\n    pub const fn try_from_mins(mins: u64) -> Result<Self, DurationNanosOutOfRangeError> {\n        Self::try_from_units(mins, NANOSECONDS_IN_MINUTE, \"minutes\")\n    }\n\n    /// Creates a duration from a number of whole hours.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result exceeds [`DurationNanos::MAX`].\n    #[must_use]","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L156-L192","documentation":"`DurationNanos::from_mins` converts whole minutes (u64) to nanoseconds and panics if the product `mins * 60 * 1_000_000_000` exceeds `DurationNanos::MAX`. It is the panicking front-end of `try_from_mins`, kept `const` so it can be used in const contexts; overflow is treated as a programmer error.","triggerScenarios":"Calling `DurationNanos::from_mins(m)` with `m > u64::MAX / 60_000_000_000` (i.e. `m >= 307_445_734` minutes, about 584 years), making `try_from_mins` return Err and the panic arm fire.","commonSituations":"Encoding 'unlimited' or 'forever' as u64::MAX in config; accidental unit confusion (value is actually seconds or nanos); synthetic/fuzz inputs spanning the full u64 range.","solutions":["Switch to `DurationNanos::try_from_mins(mins)` and handle the error.","Validate `mins <= u64::MAX / 60_000_000_000` before the call.","Clamp to `DurationNanos::MAX` if saturation is acceptable.","Correct the unit of the configured value."],"exampleFix":"// before\nlet dur = DurationNanos::from_mins(lease_mins);\n\n// after\nconst MAX_MINS: u64 = u64::MAX / 60_000_000_000;\nlet dur = if lease_mins > MAX_MINS {\n    DurationNanos::MAX\n} else {\n    DurationNanos::from_mins(lease_mins)\n};","handlingStrategy":"validation","validationCode":"const MAX_FROM_MINS: u64 = u64::MAX / 60_000_000_000;\nfn can_convert_mins(m: u64) -> bool { m <= MAX_FROM_MINS }","typeGuard":"fn fits_duration_mins(m: u64) -> Option<DurationNanos> {\n    DurationNanos::try_from_mins(m).ok()\n}","tryCatchPattern":null,"preventionTips":["Range-check minute-based config before constructing durations.","Prefer try_from_mins when the input origin is untrusted.","Keep unit conversion in one place to avoid min/sec mix-ups."],"tags":["rust","panic","integer-overflow","duration"],"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"}