nautechsystems/nautilus_trader · error

Lighter candles only support LAST price type

Error message

Lighter candles only support LAST price type

What it means

Lighter candles are only quoted at last-trade price, so `TryFrom<&BarType> for LighterCandleResolution` requires the bar spec's price type to be `PriceType::Last`. Any other price type (Bid, Ask, Mid, etc.) fails with this error.

Source

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

    ///
    /// `1w` is REST-only; the streaming channel only carries `1m`..=`1d`.
    #[must_use]
    pub const fn is_ws_streamable(self) -> bool {
        !matches!(self, Self::OneWeek)
    }
}

impl TryFrom<&BarType> for LighterCandleResolution {
    type Error = anyhow::Error;

    fn try_from(value: &BarType) -> Result<Self, Self::Error> {
        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}"),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use `PriceType::Last` in the bar spec for Lighter candles.
  2. Change bar spec strings from `...-BID`/`...-ASK`/`...-MID` to `...-LAST`.
  3. For bid/ask-based bars, aggregate locally from Lighter quotes/trades.

Example fix

// before
let bar_type = BarType::from("BTCUSDT-PERP.LIGHTER-1-MINUTE-BID-EXTERNAL");
// after
let bar_type = BarType::from("BTCUSDT-PERP.LIGHTER-1-MINUTE-LAST-EXTERNAL");
Defensive patterns

Strategy: validation

Validate before calling

if bar_type.spec().price_type != PriceType::Last {
    panic!("Lighter candles require LAST price type");
}

Type guard

fn is_last_price_bar(bar: &BarType) -> bool {
    bar.spec().price_type == PriceType::Last
}

Try / catch

let resolution = LighterCandleResolution::try_from(&bar_type)
    .map_err(|e| { eprintln!("unsupported bar spec {bar_type}: {e:#}"); e })?;

Prevention

When it happens

Trigger: Converting a BarType with `price_type != PriceType::Last` (e.g. `1-MINUTE-BID-EXTERNAL`) into a LighterCandleResolution, typically when subscribing for Lighter bars.

Common situations: Configuring bid/ask bars for Lighter because other venue adapters support them; copy-pasted bar specs from FX/crypto adapters where BID/ASK bars are common.

Related errors


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