{"record":{"id":"90404652c65198e3","repo":"nautechsystems/nautilus_trader","slug":"derive-only-supports-hour-intervals-1-4-8","errorCode":null,"errorMessage":"Derive only supports hour intervals 1, 4, 8","messagePattern":"Derive only supports hour intervals 1, 4, 8","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/derive/src/websocket/parse.rs","lineNumber":664,"sourceCode":"/// # 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\");\n            }\n            Ok(604800)\n        }\n        _ => anyhow::bail!(\"Derive does not support {aggregation:?} bars\"),\n    }\n}\n\nfn timestamp_seconds_to_nanos(value: u64, field: &str) -> anyhow::Result<UnixNanos> {","sourceCodeStart":646,"sourceCodeEnd":682,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/websocket/parse.rs#L646-L682","documentation":"Validation branch in bar_spec_to_derive_period rejecting HOUR steps other than 1, 4, or 8: Derive candle periods are fixed seconds values (3600/14400/28800) and other hourly steps have no Derive equivalent.","triggerScenarios":"Requesting bars with BarAggregation::Hour and a step not in {1,4,8} (e.g. 2, 6, 12, 24), via request_bars or bar config.","commonSituations":"Requesting 12-hour or 24-hour bars (24h should be Day step 1); configs ported from venues supporting arbitrary hour intervals.","solutions":["Use hour steps 1, 4, or 8 only","For 24-hour bars, use BarAggregation::Day with step 1","For other multiples, aggregate from a supported base interval in the strategy","Update the BarType specification in the bar request/subscription"],"exampleFix":"// before\nBarAggregation::Hour, step: 12\n// after\nBarAggregation::Hour, step: 8 // or Day/1 for 24h","handlingStrategy":"validation","validationCode":"fn hour_step_ok(step: u64) -> bool { matches!(step, 1 | 4 | 8) }\nassert!(hour_step_ok(bar_spec.step), \"Hour bars must be 1, 4, or 8\");","typeGuard":null,"tryCatchPattern":"match bar_spec_to_derive_period(&BarAggregation::Hour, step) {\n    Ok(p) => subscribe(p),\n    Err(e) if e.to_string().contains(\"hour intervals\") => {\n        // fall back to nearest supported step\n        subscribe(bar_spec_to_derive_period(&BarAggregation::Hour, nearest_supported(step))?)\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Use only Hour steps 1, 4, 8 in bar configs","Convert 24-hour requests to Day/1","Add a config lint that validates bar specs per venue 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"}