{"record":{"id":"c969986acb028dfa","repo":"nautechsystems/nautilus_trader","slug":"only-external-aggregation-is-supported-c96998","errorCode":null,"errorMessage":"Only EXTERNAL aggregation is supported","messagePattern":"Only EXTERNAL aggregation is supported","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/deribit/src/http/client.rs","lineNumber":1374,"sourceCode":"    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - Aggregation source is not EXTERNAL\n    /// - Bar aggregation type is not supported by Deribit\n    /// - The instrument is not found in cache\n    /// - The request fails or response cannot be parsed\n    ///\n    /// # Supported Resolutions\n    ///\n    /// Deribit supports: 1, 3, 5, 10, 15, 30, 60, 120, 180, 360, 720 minutes, and 1D (daily)\n    pub async fn request_bars(\n        &self,\n        bar_type: BarType,\n        start: Option<Timestamp>,\n        end: Option<Timestamp>,\n        limit: Option<u32>,\n    ) -> anyhow::Result<Vec<Bar>> {\n        anyhow::ensure!(\n            bar_type.aggregation_source() == AggregationSource::External,\n            \"Only EXTERNAL aggregation is supported\"\n        );\n\n        let now = Timestamp::now();\n\n        // Default to last hour if no start/end provided\n        let end_dt = end.unwrap_or(now);\n        let start_dt = start.unwrap_or(end_dt - jiff::SignedDuration::from_hours(1));\n\n        if let (Some(s), Some(e)) = (start, end) {\n            anyhow::ensure!(s < e, \"Invalid time range: start={s:?} end={e:?}\");\n        }\n\n        // Convert BarType to Deribit resolution\n        let spec = bar_type.spec();\n        let step = spec.step.get();\n        let resolution = match spec.aggregation {","sourceCodeStart":1356,"sourceCodeEnd":1392,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/deribit/src/http/client.rs#L1356-L1392","documentation":"request_bars only supports bars whose AggregationSource is External, i.e. bars the exchange (Deribit's TradingView chart data endpoint) produces. Internally aggregated bar types would require the client to build bars from raw trades, which it does not do, so anyhow::ensure! rejects them up front.","triggerScenarios":"Calling request_bars with a BarType created via BarType::new with AggregationSource::Internal (the default for internal aggregators), e.g. BTC-PERPETUAL*1-MINUTE*INTERNAL.","commonSituations":"Registering a data request with the internal aggregation source in a strategy config; copying BarType specs from a system where the internal aggregator synthesizes bars; confusion between live internal aggregation and historical external requests.","solutions":["Change the BarType to AggregationSource::External, e.g. BarType::from_spec with `BarAggregationSource::External`.","If internal aggregation is required, aggregate locally from trades/bars streamed over websocket instead of calling request_bars.","Check the BarType string/spec in config so it reads ...*EXTERNAL."],"exampleFix":"// before\nlet bar_type = BarType::new(instrument_id, BarAggregation::Minute, 1, PriceType::Last, AggregationSource::Internal);\n// after\nlet bar_type = BarType::new(instrument_id, BarAggregation::Minute, 1, PriceType::Last, AggregationSource::External);","handlingStrategy":"validation","validationCode":"if bar_type.aggregation_source() != AggregationSource::External {\n    bar_type = BarType::new(bar_type.instrument_id(), bar_type.aggregation(), bar_type.step(), bar_type.price_type(), AggregationSource::External);\n}","typeGuard":"fn is_external(b: &BarType) -> bool {\n    b.aggregation_source() == AggregationSource::External\n}","tryCatchPattern":"match client.request_bars(bar_type, start, end, limit).await {\n    Ok(bars) => bars,\n    Err(e) if e.to_string().contains(\"Only EXTERNAL\") => {\n        // fall back to subscribing to external bar data over websocket\n        Vec::new()\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Create historical-request BarTypes with AggregationSource::External","Do not reuse BarTypes configured for the internal aggregator in historical requests","Check BarType strings in config end with *EXTERNAL","Use internal aggregation only with a local aggregator fed by streamed data"],"tags":["deribit","bars","aggregation","validation"],"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"}