{"record":{"id":"71c657f62a03aba2","repo":"nautechsystems/nautilus_trader","slug":"step-exceeds-i32-range-for-year-arithmetic","errorCode":null,"errorMessage":"`step` exceeds i32 range for year arithmetic","messagePattern":"`step` exceeds i32 range for year arithmetic","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/bar.rs","lineNumber":287,"sourceCode":"                start_time =\n                    subtract_n_months(start_time, 12).expect(\"Failed to subtract 12 months\");\n            }\n\n            let months_step =\n                u32::try_from(step).expect(\"`step` exceeds u32 range for month arithmetic\");\n\n            while start_time <= now {\n                start_time =\n                    add_n_months(start_time, months_step).expect(\"Failed to add months in loop\");\n            }\n\n            start_time =\n                subtract_n_months(start_time, months_step).expect(\"Failed to subtract months_step\");\n            start_time\n        }\n        BarAggregation::Year => {\n            let step_i32 =\n                i32::try_from(step).expect(\"`step` exceeds i32 range for year arithmetic\");\n\n            // Reconstruct from Jan 1 + origin each time to avoid leap-day drift\n            let year_start = |year: i32| {\n                let year = i16::try_from(year).expect(\"year exceeds Jiff supported range\");\n                Offset::UTC\n                    .to_timestamp(\n                        Date::new(year, 1, 1)\n                            .expect(\"valid year start date\")\n                            .at(0, 0, 0, 0),\n                    )\n                    .expect(\"valid UTC year start\")\n                    + origin_offset\n            };\n\n            let mut year = i32::from(Offset::UTC.to_datetime(now).year());\n            if year_start(year) > now {\n                year = year\n                    .checked_sub(step_i32)","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/bar.rs#L269-L305","documentation":"For Year bars, the step (i64) is narrowed to i32 for year arithmetic; if the value exceeds i32::MAX (or is negative), try_from fails and the expect panics. The function explicitly documents that `step` must be representable for the calendar arithmetic.","triggerScenarios":"get_time_bar_start (or start_timer_internal registering the timer) with BarAggregation::Year and a spec step > 2,147,483,647 years, or a negative step.","commonSituations":"Unit confusion when building the BarType spec (passing nanoseconds or seconds as the year step); programmatic spec generation without bounds checks; corrupted configuration files.","solutions":["Fix the Year bar step to the intended small positive integer of years.","Validate 0 < step <= i32::MAX before constructing the BarType.","Reject such bar specs at configuration-parse time rather than at timer registration.","If a huge period is genuinely needed, compose it via Month/Day aggregation instead."],"exampleFix":"// before\nBarType::from_spec(10_000_000_000, BarAggregation::Year)\n// after\nassert!(step > 0 && step <= i32::MAX as i64);\nBarType::from_spec(step, BarAggregation::Year)","handlingStrategy":"validation","validationCode":"fn validate_year_step(spec: &BarSpec) -> Result<(), String> {\n    if spec.aggregation != BarAggregation::Year { return Ok(()); }\n    let step = step_to_i64(spec.step);\n    if step <= 0 { return Err(\"year step must be positive\".into()); }\n    if step > i32::MAX as i64 { return Err(\"year step exceeds i32 range\".into()); }\n    Ok(())\n}","typeGuard":"fn valid_year_step(step: i64) -> bool { step > 0 && step <= i32::MAX as i64 }","tryCatchPattern":"let start = std::panic::catch_unwind(|| get_time_bar_start(now, &bar_type, origin))\n    .map_err(|_| anyhow::anyhow!(\"invalid year step for {bar_type}\"))?;","preventionTips":["Validate bar spec steps when loading strategy configuration.","Reject absurd steps (years should be single/double digits in practice).","Add unit tests for spec construction from raw config values."],"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-14T05:17:10.506Z"}