{"record":{"id":"5bc361fafe161e57","repo":"nautechsystems/nautilus_trader","slug":"aggregation-not-time-based","errorCode":null,"errorMessage":"Aggregation not time based","messagePattern":"Aggregation not time based","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/data/bar.rs","lineNumber":192,"sourceCode":"\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.\n#[must_use]\npub fn get_bar_interval_ns(bar_type: &BarType) -> DurationNanos {\n    DurationNanos::try_from(get_bar_interval(bar_type)).expect(\"Invalid bar interval\")\n}\n\n/// Returns the time bar start as a timezone-aware `Timestamp`.\n///\n/// # Panics\n///\n/// Panics if computing the base civil date or datetime from `now` fails,","sourceCodeStart":174,"sourceCodeEnd":210,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/data/bar.rs#L174-L210","documentation":"`get_bar_interval` converts a `BarType`'s specification into a `SignedDuration`. Only time-based aggregations (Millisecond, Second, Minute, Hour, Day, Week, Month, Year) have a duration; the fallthrough `_ => panic!(\"Aggregation not time based\")` fires for non-time aggregations (e.g. Tick, Value/Dollar). The library panics because the function's signature cannot express 'not applicable'.","triggerScenarios":"Passing a BarType whose BarSpecification.aggregation is Tick or Value (non-time based) to `get_bar_interval`, directly or indirectly through `get_bar_interval_ns`.","commonSituations":"Code that computes bar intervals generically over all bar types in a portfolio/config, where some instruments use tick bars or volume/dollar bars; calling interval math in a shared timer routine without filtering aggregation kind.","solutions":["Check `bar_type.spec().aggregation` is a time-based variant before calling `get_bar_interval`.","Restrict the call site to time-based bar types and handle tick/value bars with different logic.","Use the `_checked`/fallible sibling API (`try_time_interval`) instead of the panicking helper if available for your use case."],"exampleFix":"// before\nlet interval = get_bar_interval(&bar_type); // panics for TICK bars\n\n// after\nuse BarAggregation::*;\nlet interval = match bar_type.spec().aggregation {\n    Millisecond | Second | Minute | Hour | Day | Week | Month | Year => get_bar_interval(&bar_type),\n    _ => return Err(anyhow::anyhow!(\"non-time bar aggregation\")),\n};","handlingStrategy":"validation","validationCode":"// Rust\nfn is_time_based(a: BarAggregation) -> bool {\n    use BarAggregation::*;\n    matches!(a, Millisecond | Second | Minute | Hour | Day | Week | Month | Year)\n}\n// call site\ndebug_assert!(is_time_based(bar_type.spec().aggregation));","typeGuard":"fn is_time_based(a: BarAggregation) -> bool {\n    use BarAggregation::*;\n    matches!(a, Millisecond | Second | Minute | Hour | Day | Week | Month | Year)\n}","tryCatchPattern":null,"preventionTips":["Filter bar types to time-based aggregations before interval math","Keep tick/value bar handling in separate event-driven code paths","Validate BarSpec strings from config at load time"],"tags":["rust","bars","aggregation","panic"],"backgroundTag":"unsupported-operation","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"}