{"record":{"id":"f40995c0392b7614","repo":"nautechsystems/nautilus_trader","slug":"lighter-index-price-subscriptions-require-a-perpet","errorCode":null,"errorMessage":"Lighter index price subscriptions require a perpetual or spot instrument: {instrument_id}","messagePattern":"Lighter index price subscriptions require a perpetual or spot instrument: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/data/mod.rs","lineNumber":822,"sourceCode":"        &self,\n        instrument_id: InstrumentId,\n    ) -> anyhow::Result<LighterWsChannel> {\n        let instrument = self\n            .instruments\n            .get_cloned(&instrument_id)\n            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;\n        let market_index = self.registry.market_index(&instrument_id).ok_or_else(|| {\n            anyhow::anyhow!(\"No Lighter market_index registered for {instrument_id}\")\n        })?;\n\n        match instrument {\n            InstrumentAny::CryptoPerpetual(_) => Ok(LighterWsChannel::MarketStats(\n                LighterMarketSelection::Market(market_index),\n            )),\n            InstrumentAny::CurrencyPair(_) => Ok(LighterWsChannel::SpotMarketStats(\n                LighterMarketSelection::Market(market_index),\n            )),\n            _ => anyhow::bail!(\n                \"Lighter index price subscriptions require a perpetual or spot instrument: {instrument_id}\",\n            ),\n        }\n    }\n}\n\nasync fn await_instrument_refresh<T>(\n    cancellation: &CancellationToken,\n    request: impl std::future::Future<Output = T>,\n) -> Option<T> {\n    tokio::select! {\n        biased;\n        () = cancellation.cancelled() => None,\n        result = request => (!cancellation.is_cancelled()).then_some(result),\n    }\n}\n\nfn cache_lighter_instrument_status(","sourceCodeStart":804,"sourceCodeEnd":840,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/data/mod.rs#L804-L840","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Use a CryptoPerpetual or CurrencyPair (spot) instrument_id for index price subscriptions.","Ensure the instrument is added to the cache first (add_instrument / request_instruments) so it resolves to the right type.","If you need index-like data for another instrument type, use the applicable channel or compute it from constituent data.","Verify the instrument_id format matches Lighter's convention (venue-qualified symbol)."],"exampleFix":"// before\nclient.subscribe_index_prices(InstrumentId::from(\"ESZ6.CME\"))?; // future: unsupported\n// after\nclient.subscribe_index_prices(InstrumentId::from(\"BTC-USD.PERP.LIGHTER\"))?; // perpetual","handlingStrategy":"validation","validationCode":"let instrument = cache.instrument(&instrument_id)\n    .ok_or_else(|| anyhow::anyhow!(\"instrument not in cache: {instrument_id}\"))?;\nassert!(matches!(instrument, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CurrencyPair(_)), \"index price subscription needs a perp or spot instrument: {instrument_id}\");","typeGuard":"fn is_perp_or_spot(inst: &InstrumentAny) -> bool {\n    matches!(inst, InstrumentAny::CryptoPerpetual(_) | InstrumentAny::CurrencyPair(_))\n}","tryCatchPattern":null,"preventionTips":["Load instruments into the cache before subscribing.","Only target perpetual/spot instruments for index price subscriptions.","Check instrument_id spelling and venue suffix."],"tags":["rust","adapter","websocket","subscription","instrument"],"backgroundTag":"unsupported-operation","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"}