{"record":{"id":"8aac4073c9a7bfff","repo":"nautechsystems/nautilus_trader","slug":"lighter-candles-only-support-last-price-type","errorCode":null,"errorMessage":"Lighter candles only support LAST price type","messagePattern":"Lighter candles only support LAST price type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/common/enums.rs","lineNumber":256,"sourceCode":"    ///\n    /// `1w` is REST-only; the streaming channel only carries `1m`..=`1d`.\n    #[must_use]\n    pub const fn is_ws_streamable(self) -> bool {\n        !matches!(self, Self::OneWeek)\n    }\n}\n\nimpl TryFrom<&BarType> for LighterCandleResolution {\n    type Error = anyhow::Error;\n\n    fn try_from(value: &BarType) -> Result<Self, Self::Error> {\n        anyhow::ensure!(\n            value.aggregation_source() == AggregationSource::External,\n            \"Lighter candles only support EXTERNAL aggregation\",\n        );\n\n        let spec = value.spec();\n        anyhow::ensure!(\n            spec.price_type == PriceType::Last,\n            \"Lighter candles only support LAST price type\",\n        );\n\n        let step = spec.step.get();\n        match spec.aggregation {\n            BarAggregation::Minute => match step {\n                1 => Ok(Self::OneMinute),\n                5 => Ok(Self::FiveMinute),\n                15 => Ok(Self::FifteenMinute),\n                30 => Ok(Self::ThirtyMinute),\n                _ => anyhow::bail!(\"unsupported Lighter candle minute step: {step}\"),\n            },\n            BarAggregation::Hour => match step {\n                1 => Ok(Self::OneHour),\n                4 => Ok(Self::FourHour),\n                12 => Ok(Self::TwelveHour),\n                _ => anyhow::bail!(\"unsupported Lighter candle hour step: {step}\"),","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/common/enums.rs#L238-L274","documentation":"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.","triggerScenarios":"Converting a BarType with `price_type != PriceType::Last` (e.g. `1-MINUTE-BID-EXTERNAL`) into a LighterCandleResolution, typically when subscribing for Lighter bars.","commonSituations":"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.","solutions":["Use `PriceType::Last` in the bar spec for Lighter candles.","Change bar spec strings from `...-BID`/`...-ASK`/`...-MID` to `...-LAST`.","For bid/ask-based bars, aggregate locally from Lighter quotes/trades."],"exampleFix":"// before\nlet bar_type = BarType::from(\"BTCUSDT-PERP.LIGHTER-1-MINUTE-BID-EXTERNAL\");\n// after\nlet bar_type = BarType::from(\"BTCUSDT-PERP.LIGHTER-1-MINUTE-LAST-EXTERNAL\");","handlingStrategy":"validation","validationCode":"if bar_type.spec().price_type != PriceType::Last {\n    panic!(\"Lighter candles require LAST price type\");\n}","typeGuard":"fn is_last_price_bar(bar: &BarType) -> bool {\n    bar.spec().price_type == PriceType::Last\n}","tryCatchPattern":"let resolution = LighterCandleResolution::try_from(&bar_type)\n    .map_err(|e| { eprintln!(\"unsupported bar spec {bar_type}: {e:#}\"); e })?;","preventionTips":["Use ...-LAST-EXTERNAL bar specs exclusively for Lighter.","Validate all configured bar types when the node starts.","Remember Lighter only publishes last-trade candles."],"tags":["bars","price-type","validation","lighter"],"backgroundTag":"unsupported-enum-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}