{"record":{"id":"e4e9b85a25435e28","repo":"nautechsystems/nautilus_trader","slug":"derive-only-supports-minute-intervals-1-5-15-30","errorCode":null,"errorMessage":"Derive only supports minute intervals 1, 5, 15, 30 (use HOUR for >= 60)","messagePattern":"Derive only supports minute intervals 1, 5, 15, 30 \\(use HOUR for >= 60\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/derive/src/websocket/parse.rs","lineNumber":656,"sourceCode":"}\n\n/// Maps a Nautilus bar aggregation and step to the Derive `period` enum value\n/// (bucket size in seconds).\n///\n/// Derive supports the following bucket sizes: 60, 300, 900, 1800, 3600,\n/// 14400, 28800, 86400, 604800.\n///\n/// # Errors\n///\n/// Returns an error if the aggregation or step has no Derive equivalent.\npub fn bar_spec_to_derive_period(aggregation: BarAggregation, step: u64) -> anyhow::Result<u32> {\n    match aggregation {\n        BarAggregation::Minute => match step {\n            1 => Ok(60),\n            5 => Ok(300),\n            15 => Ok(900),\n            30 => Ok(1800),\n            _ => anyhow::bail!(\n                \"Derive only supports minute intervals 1, 5, 15, 30 (use HOUR for >= 60)\"\n            ),\n        },\n        BarAggregation::Hour => match step {\n            1 => Ok(3600),\n            4 => Ok(14400),\n            8 => Ok(28800),\n            _ => anyhow::bail!(\"Derive only supports hour intervals 1, 4, 8\"),\n        },\n        BarAggregation::Day => {\n            if step != 1 {\n                anyhow::bail!(\"Derive only supports 1 DAY interval bars\");\n            }\n            Ok(86400)\n        }\n        BarAggregation::Week => {\n            if step != 1 {\n                anyhow::bail!(\"Derive only supports 1 WEEK interval bars\");","sourceCodeStart":638,"sourceCodeEnd":674,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/websocket/parse.rs#L638-L674","documentation":"bar_spec_to_derive_period converts Nautilus BarAggregationSpec into Derive candle periods. Minute aggregation only supports steps 1, 5, 15, and 30; other minute steps bail, with a hint to use Hour aggregation for >= 60 minutes.","triggerScenarios":"Requesting bars with BarAggregation::Minute and a step not in {1,5,15,30} (e.g. 2, 10, 45, 60), via request_bars or a bar subscription config.","commonSituations":"Config requesting 60-minute bars as Minute(60) instead of Hour(1); strategies tuned to 10-minute bars from other venues.","solutions":["Use one of the supported minute steps: 1, 5, 15, or 30","For 60+ minute intervals, switch to BarAggregation::Hour with an appropriate step (1, 4, 8)","Aggregate unsupported intervals client-side (e.g. build 10-min bars from 1-min bars in the strategy)","Adjust the BarType/BarSpecification in the request_bars call or bar subscription config"],"exampleFix":"// before\nBarAggregation::Minute, step: 60\n// after\nBarAggregation::Hour, step: 1","handlingStrategy":"validation","validationCode":"fn minute_step_ok(step: u64) -> bool { matches!(step, 1 | 5 | 15 | 30) }\nassert!(minute_step_ok(bar_spec.step), \"use Minute 1/5/15/30 or Hour\");","typeGuard":null,"tryCatchPattern":"match bar_spec_to_derive_period(&agg, step) {\n    Ok(p) => subscribe(p),\n    Err(e) if e.to_string().contains(\"minute intervals\") => {\n        subscribe(bar_spec_to_derive_period(&BarAggregation::Hour, 1)?)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Constrain bar configs to Derive-supported steps (Minute 1/5/15/30)","Map 60-minute requests to Hour/1 automatically in config loading","Test bar specs against the adapter's supported matrix at startup"],"tags":["rust","bars","aggregation","validation"],"backgroundTag":"invalid-argument-value","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"}