{"record":{"id":"76b85a1b6d06860c","repo":"nautechsystems/nautilus_trader","slug":"lighter-label-subscriptions-require-a-perpetual","errorCode":null,"errorMessage":"Lighter {label} subscriptions require a perpetual instrument: {instrument_id}","messagePattern":"Lighter (.+?) subscriptions require a perpetual instrument: (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/data/mod.rs","lineNumber":789,"sourceCode":"            self.spawn_task(async move {\n                if let Err(e) = unsubscribe_market_stats_channel(ws, channel).await {\n                    log::error!(\"Failed to unsubscribe from Lighter {label}: {e:?}\");\n                }\n            });\n        }\n    }\n\n    fn perp_market_stats_channel(\n        &self,\n        instrument_id: InstrumentId,\n        label: &str,\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\n        anyhow::ensure!(\n            matches!(instrument, InstrumentAny::CryptoPerpetual(_)),\n            \"Lighter {label} subscriptions require a perpetual instrument: {instrument_id}\",\n        );\n\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        Ok(LighterWsChannel::MarketStats(\n            LighterMarketSelection::Market(market_index),\n        ))\n    }\n\n    fn index_market_stats_channel(\n        &self,\n        instrument_id: InstrumentId,\n    ) -> anyhow::Result<LighterWsChannel> {\n        let instrument = self","sourceCodeStart":771,"sourceCodeEnd":807,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/data/mod.rs#L771-L807","documentation":"perp_market_stats_channel resolves an instrument to a Lighter MarketStats websocket channel, but only CryptoPerpetual instruments are eligible. The instrument was found in the local cache yet is not a perpetual (e.g. a spot or other instrument type), so the subscription is refused.","triggerScenarios":"Calling subscribe_mark_prices or subscribe_funding_rates with an InstrumentId that resolves to a non-perpetual cached instrument — e.g. requesting mark prices or funding rates for a spot pair.","commonSituations":"Subscribing to funding rates for spot instruments (which have none); a stale or wrong instrument ID pointing at a spot symbol; configuring subscriptions from a symbol list that mixes spot and perp symbols.","solutions":["Use a perpetual instrument ID (e.g. the PERP symbol) for mark-price and funding-rate subscriptions.","Filter your subscription list to perpetual instruments before calling subscribe_mark_prices/subscribe_funding_rates.","Check the instrument cache to confirm what type the ID resolves to."],"exampleFix":"// before\ndata.subscribe_funding_rates(InstrumentId::from(\"ETH/USDT.LIGHTER\"))?; // spot\n// after\ndata.subscribe_funding_rates(InstrumentId::from(\"ETH-PERP.USDT.LIGHTER\"))?;","handlingStrategy":"validation","validationCode":"if !instrument_id.symbol.value.ends_with(\"-PERP\") {\n    return Err(anyhow::anyhow!(\"mark price/funding requires a perp: {instrument_id}\"));\n}","typeGuard":"fn is_perp(inst: &InstrumentAny) -> bool { matches!(inst, InstrumentAny::CryptoPerpetual(_)) }","tryCatchPattern":"match subscribe_funding_rates(instrument_id) {\n    Ok(()) => (),\n    Err(e) if e.to_string().contains(\"require a perpetual\") => warn!(\"skip non-perp {instrument_id}\"),\n    Err(e) => return Err(e),\n}","preventionTips":["Filter subscription lists to CryptoPerpetual instruments before requesting mark prices or funding rates","Do not request funding rates for spot pairs — they only exist for perps","Check instrument type in the cache before building subscription requests"],"tags":["subscription","instrument-type","websocket","lighter"],"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"}