{"record":{"id":"f46ed2822d47ea2c","repo":"nautechsystems/nautilus_trader","slug":"step-overflows-i64-days","errorCode":null,"errorMessage":"`step` overflows i64 days","messagePattern":"`step` overflows i64 days","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/bar.rs","lineNumber":182,"sourceCode":"/// Returns the bar interval as a [`SignedDuration`].\n///\n/// # Panics\n///\n/// Panics if the aggregation method of the given `bar_type` is not time based,\n/// or if `step` is too large for the interval arithmetic.\n#[must_use]\npub fn get_bar_interval(bar_type: &BarType) -> SignedDuration {\n    let spec = bar_type.spec();\n    let step = step_to_i64(spec.step);\n\n    match spec.aggregation {\n        BarAggregation::Millisecond => SignedDuration::from_millis(step),\n        BarAggregation::Second => SignedDuration::from_secs(step),\n        BarAggregation::Minute => SignedDuration::from_mins(step),\n        BarAggregation::Hour => SignedDuration::from_hours(step),\n        BarAggregation::Day => duration_days(step),\n        BarAggregation::Week => {\n            duration_days(step.checked_mul(7).expect(\"`step` overflows i64 days\"))\n        }\n        BarAggregation::Month => {\n            // Proxy for comparing bar lengths\n            duration_days(step.checked_mul(30).expect(\"`step` overflows i64 days\"))\n        }\n        BarAggregation::Year => {\n            // Proxy for comparing bar lengths\n            duration_days(step.checked_mul(365).expect(\"`step` overflows i64 days\"))\n        }\n        _ => panic!(\"Aggregation not time based\"),\n    }\n}\n\n/// Returns the bar interval as [`DurationNanos`].\n///\n/// # Panics\n///\n/// Panics if the aggregation method of the given `bar_type` is not time based.","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/bar.rs#L164-L200","documentation":"In `get_bar_interval` (crates/model/src/data/bar.rs:182), a Week aggregation multiplies the step by 7 days with `step.checked_mul(7).expect(\"`step` overflows i64 days\")`. If `step` is large enough that step*7 exceeds i64, the checked multiplication returns None and the code panics. It is a deliberate arithmetic-overflow guard on user-supplied bar aggregation steps.","triggerScenarios":"Calling `get_bar_interval`/`get_bar_interval_ns` with a `BarType` whose bar aggregation is Week and whose step value is near/above i64::MAX/7 (e.g. an absurdly large step parsed from configuration or an adversarial input).","commonSituations":"Mistyped aggregation step in a config file (e.g. a step in nanoseconds pasted where days were expected); programmatic construction of BarType with an unvalidated step; tests exercising the overflow path.","solutions":["Use a sane step value: step is in units of the aggregation (days for Week), so keep step * 7 well within i64 (practically step << 1.3e18).","Validate the step when building the BarType (reject steps above a practical maximum such as u32 range) before aggregation starts.","Check where the BarType is constructed (config parse, Python binding) and clamp or reject oversized steps there."],"exampleFix":"// before\nlet bar_type = BarType::new(instrument_id, BarAggregation::Week, 9_223_372_036_854_775_807, PriceType::Last);\n// after\nlet step = 9_223_372_036_854_775_807;\nassert!(step <= i64::MAX / 7, \"week step too large\");\nlet bar_type = BarType::new(instrument_id, BarAggregation::Week, step, PriceType::Last);","handlingStrategy":"validation","validationCode":"// rust\nfn week_step_ok(step: i64) -> bool { step > 0 && step <= i64::MAX / 7 }","typeGuard":null,"tryCatchPattern":"// Panics are not catchable in Rust; validate before constructing the BarType.\nif !week_step_ok(step) { return Err(BarConfigError::StepTooLarge(step)); }","preventionTips":["Treat `step` as a count of aggregation units (weeks), not seconds/nanos.","Validate steps at configuration load time, before creating BarTypes or aggregators.","Add unit tests covering your maximum configured step."],"tags":["rust","panic","integer-overflow","bar-aggregation"],"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"}