{"record":{"id":"245c627b9b9f67ce","repo":"nautechsystems/nautilus_trader","slug":"lighter-candles-only-support-external-aggregation","errorCode":null,"errorMessage":"Lighter candles only support EXTERNAL aggregation","messagePattern":"Lighter candles only support EXTERNAL aggregation","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/common/enums.rs","lineNumber":250,"sourceCode":"            Self::OneWeek => (1, BarAggregation::Week),\n        };\n        BarSpecification::new(step, aggregation, PriceType::Last)\n    }\n\n    /// Returns `true` when this resolution is offered on the candle WebSocket stream.\n    ///\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}\"),","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/common/enums.rs#L232-L268","documentation":"Converting a Nautilus `BarType` into a `LighterCandleResolution` requires the bar's aggregation source to be `AggregationSource::External`, because Lighter provides candles directly and the adapter does not aggregate bars internally. `TryFrom<&BarType>` fails with this error for any internally-aggregated bar type.","triggerScenarios":"Requesting Lighter candle data with a BarType whose spec uses `AggregationSource::Internal` (e.g. bars aggregated by the Nautilus data engine from ticks).","commonSituations":"Subscribing to bars with the default internal aggregation instead of declaring EXTERNAL bars; copying BarType strings like `BTCUSDT-PERP.LIGHTER-*MINUTE-INTERNAL` from a config that targeted a different venue.","solutions":["Create the BarType with `AggregationSource::External` (e.g. `BarType::new(instrument_id, BarAggregation::Minute, PriceType::Last, AggregationSource::External)`).","Update any bar spec strings in config from `...-INTERNAL` to `...-EXTERNAL`.","If internal aggregation is required, aggregate locally from Lighter trades/ticks instead of using Lighter candles."],"exampleFix":"// before\nlet bar_type = BarType::from(\"BTCUSDT-PERP.LIGHTER-1-MINUTE-LAST-INTERNAL\");\n// after\nlet bar_type = BarType::from(\"BTCUSDT-PERP.LIGHTER-1-MINUTE-LAST-EXTERNAL\");","handlingStrategy":"validation","validationCode":"if bar_type.aggregation_source() != AggregationSource::External {\n    panic!(\"Lighter candles require EXTERNAL aggregation\");\n}","typeGuard":"fn is_external_bar(bar: &BarType) -> bool {\n    bar.aggregation_source() == AggregationSource::External\n}","tryCatchPattern":"let resolution = LighterCandleResolution::try_from(&bar_type)\n    .map_err(|e| { eprintln!(\"bad bar type {bar_type}: {e:#}\"); e })?;","preventionTips":["Always declare Lighter bar types with -EXTERNAL aggregation.","Validate bar spec strings in config at startup.","Never copy INTERNAL bar specs from other venues."],"tags":["bars","aggregation","validation","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-14T05:17:10.506Z"}