nautechsystems/nautilus_trader · error

unsupported Lighter candle minute step: {step}

Error message

unsupported Lighter candle minute step: {step}

What it means

This error comes from the TryFrom conversion that maps a Nautilus bar specification (BarAggregation::Minute plus a step) to a Lighter WS candle interval. Lighter only exposes 1, 5, 15, and 30 minute candles, so any other minute step is rejected with this message. It is a configuration-time validation guard, raised before any network request is made.

Source

Thrown at crates/adapters/lighter/src/common/enums.rs:268

        anyhow::ensure!(
            value.aggregation_source() == AggregationSource::External,
            "Lighter candles only support EXTERNAL aggregation",
        );

        let spec = value.spec();
        anyhow::ensure!(
            spec.price_type == PriceType::Last,
            "Lighter candles only support LAST price type",
        );

        let step = spec.step.get();
        match spec.aggregation {
            BarAggregation::Minute => match step {
                1 => Ok(Self::OneMinute),
                5 => Ok(Self::FiveMinute),
                15 => Ok(Self::FifteenMinute),
                30 => Ok(Self::ThirtyMinute),
                _ => anyhow::bail!("unsupported Lighter candle minute step: {step}"),
            },
            BarAggregation::Hour => match step {
                1 => Ok(Self::OneHour),
                4 => Ok(Self::FourHour),
                12 => Ok(Self::TwelveHour),
                _ => anyhow::bail!("unsupported Lighter candle hour step: {step}"),
            },
            BarAggregation::Day => match step {
                1 => Ok(Self::OneDay),
                _ => anyhow::bail!("unsupported Lighter candle day step: {step}"),
            },
            BarAggregation::Week => match step {
                1 => Ok(Self::OneWeek),
                _ => anyhow::bail!("unsupported Lighter candle week step: {step}"),
            },
            other => anyhow::bail!("unsupported Lighter candle aggregation: {other}"),
        }
    }

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Change the bar aggregation step to one Lighter supports: 1, 5, 15, or 30 minutes.
  2. If you need e.g. 60-minute bars, switch the BarSpec aggregation from Minute to Hour with step 1.
  3. Resample locally: subscribe to 1-minute Lighter bars and aggregate to the desired step in your strategy.
  4. If the step is dynamic, pre-validate it against {1,5,15,30} before constructing the subscription.

Example fix

// before
BarSpec::new(instrument_id, bar_spec, BarAggregation::Minute, Price::from("2")) // step 2
// after
BarSpec::new(instrument_id, bar_spec, BarAggregation::Minute, Price::from("5")) // step 5
Defensive patterns

Strategy: validation

Validate before calling

const LIGHTER_MINUTE_STEPS: [u32; 4] = [1, 5, 15, 30];
assert!(LIGHTER_MINUTE_STEPS.contains(&bar_spec.step), "Lighter minute bars support steps 1/5/15/30, got {}", bar_spec.step);

Prevention

When it happens

Trigger: Calling the (BarSpec, ...) -> LighterCandleInterval try_from with aggregation=Minute and a step not in {1, 5, 15, 30}, e.g. BarSpec step 2, 3, 10, 60 (60 belongs to Hour aggregation), when subscribing to bars or requesting historical bars from the Lighter data client.

Common situations: Requesting 2-minute or 10-minute bars in a config file; mapping another exchange's interval list onto Lighter; using a step of 60 minutes assuming minutes roll into hours; a programmatically generated BarSpec (e.g. from timedelta) not matching Lighter's fixed intervals.

Related errors


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