nautechsystems/nautilus_trader · error

Derive only supports minute intervals 1, 5, 15, 30 (use HOUR

Error message

Derive only supports minute intervals 1, 5, 15, 30 (use HOUR for >= 60)

What it means

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.

Source

Thrown at crates/adapters/derive/src/websocket/parse.rs:656

}

/// Maps a Nautilus bar aggregation and step to the Derive `period` enum value
/// (bucket size in seconds).
///
/// Derive supports the following bucket sizes: 60, 300, 900, 1800, 3600,
/// 14400, 28800, 86400, 604800.
///
/// # Errors
///
/// Returns an error if the aggregation or step has no Derive equivalent.
pub fn bar_spec_to_derive_period(aggregation: BarAggregation, step: u64) -> anyhow::Result<u32> {
    match aggregation {
        BarAggregation::Minute => match step {
            1 => Ok(60),
            5 => Ok(300),
            15 => Ok(900),
            30 => Ok(1800),
            _ => anyhow::bail!(
                "Derive only supports minute intervals 1, 5, 15, 30 (use HOUR for >= 60)"
            ),
        },
        BarAggregation::Hour => match step {
            1 => Ok(3600),
            4 => Ok(14400),
            8 => Ok(28800),
            _ => anyhow::bail!("Derive only supports hour intervals 1, 4, 8"),
        },
        BarAggregation::Day => {
            if step != 1 {
                anyhow::bail!("Derive only supports 1 DAY interval bars");
            }
            Ok(86400)
        }
        BarAggregation::Week => {
            if step != 1 {
                anyhow::bail!("Derive only supports 1 WEEK interval bars");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use one of the supported minute steps: 1, 5, 15, or 30
  2. For 60+ minute intervals, switch to BarAggregation::Hour with an appropriate step (1, 4, 8)
  3. Aggregate unsupported intervals client-side (e.g. build 10-min bars from 1-min bars in the strategy)
  4. Adjust the BarType/BarSpecification in the request_bars call or bar subscription config

Example fix

// before
BarAggregation::Minute, step: 60
// after
BarAggregation::Hour, step: 1
Defensive patterns

Strategy: validation

Validate before calling

fn minute_step_ok(step: u64) -> bool { matches!(step, 1 | 5 | 15 | 30) }
assert!(minute_step_ok(bar_spec.step), "use Minute 1/5/15/30 or Hour");

Try / catch

match bar_spec_to_derive_period(&agg, step) {
    Ok(p) => subscribe(p),
    Err(e) if e.to_string().contains("minute intervals") => {
        subscribe(bar_spec_to_derive_period(&BarAggregation::Hour, 1)?)
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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.

Common situations: Config requesting 60-minute bars as Minute(60) instead of Hour(1); strategies tuned to 10-minute bars from other venues.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/e4e9b85a25435e28. Report an issue: GitHub.