nautechsystems/nautilus_trader · error

Lighter index price subscriptions require a perpetual or spo

Error message

Lighter index price subscriptions require a perpetual or spot instrument: {instrument_id}

What it means

Raised when subscribing to index prices on the Lighter data client with an instrument that is neither a CryptoPerpetual nor a CurrencyPair (spot). Index price updates arrive via the market_stats or spot_market_stats WebSocket channels, which only make sense for those instrument types, so any other InstrumentAny variant is rejected.

Source

Thrown at crates/adapters/lighter/src/data/mod.rs:822

        &self,
        instrument_id: InstrumentId,
    ) -> anyhow::Result<LighterWsChannel> {
        let instrument = self
            .instruments
            .get_cloned(&instrument_id)
            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
        let market_index = self.registry.market_index(&instrument_id).ok_or_else(|| {
            anyhow::anyhow!("No Lighter market_index registered for {instrument_id}")
        })?;

        match instrument {
            InstrumentAny::CryptoPerpetual(_) => Ok(LighterWsChannel::MarketStats(
                LighterMarketSelection::Market(market_index),
            )),
            InstrumentAny::CurrencyPair(_) => Ok(LighterWsChannel::SpotMarketStats(
                LighterMarketSelection::Market(market_index),
            )),
            _ => anyhow::bail!(
                "Lighter index price subscriptions require a perpetual or spot instrument: {instrument_id}",
            ),
        }
    }
}

async fn await_instrument_refresh<T>(
    cancellation: &CancellationToken,
    request: impl std::future::Future<Output = T>,
) -> Option<T> {
    tokio::select! {
        biased;
        () = cancellation.cancelled() => None,
        result = request => (!cancellation.is_cancelled()).then_some(result),
    }
}

fn cache_lighter_instrument_status(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use a CryptoPerpetual or CurrencyPair (spot) instrument_id for index price subscriptions.
  2. Ensure the instrument is added to the cache first (add_instrument / request_instruments) so it resolves to the right type.
  3. If you need index-like data for another instrument type, use the applicable channel or compute it from constituent data.
  4. Verify the instrument_id format matches Lighter's convention (venue-qualified symbol).

Example fix

// before
client.subscribe_index_prices(InstrumentId::from("ESZ6.CME"))?; // future: unsupported
// after
client.subscribe_index_prices(InstrumentId::from("BTC-USD.PERP.LIGHTER"))?; // perpetual
Defensive patterns

Strategy: validation

Validate before calling

let instrument = cache.instrument(&instrument_id)
    .ok_or_else(|| anyhow::anyhow!("instrument not in cache: {instrument_id}"))?;
assert!(matches!(instrument, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CurrencyPair(_)), "index price subscription needs a perp or spot instrument: {instrument_id}");

Type guard

fn is_perp_or_spot(inst: &InstrumentAny) -> bool {
    matches!(inst, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CurrencyPair(_))
}

Prevention

When it happens

Trigger: Calling subscribe_index_prices(instrument_id) with a instrument_id resolving to a futures contract, spread, synthetic, or otherwise non-perp/non-spot instrument, or with an instrument not loaded into the cache (so it cannot be resolved to a perp/spot type).

Common situations: Pointing an index-price subscription at a dated future or option; typos/instrument-ID mismatches so the instrument isn't found and falls into the catch-all arm; reusing a subscription builder across venues with different instrument taxonomies.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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