{"record":{"id":"eb6a148ebb473ded","repo":"nautechsystems/nautilus_trader","slug":"binance-historical-bars-require-external-aggregati-eb6a14","errorCode":null,"errorMessage":"Binance historical bars require EXTERNAL aggregation","messagePattern":"Binance historical bars require EXTERNAL aggregation","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/spot/data.rs","lineNumber":2356,"sourceCode":"        });\n\n        Ok(())\n    }\n\n    fn request_bars(&self, request: RequestBars) -> anyhow::Result<()> {\n        let http = self.http_client.clone();\n        let sender = self.data_sender.clone();\n        let bar_type = request.bar_type;\n        let start = request.start;\n        let end = request.end;\n        let limit = request.limit.map(|n| n.get() as u32);\n        let request_id = request.request_id;\n        let client_id = request.client_id.unwrap_or(self.client_id);\n        let params = request.params;\n        let clock = self.clock;\n        let start_nanos = datetime_to_unix_nanos(start);\n        let end_nanos = datetime_to_unix_nanos(end);\n        anyhow::ensure!(\n            bar_type.aggregation_source() == AggregationSource::External,\n            \"Binance historical bars require EXTERNAL aggregation\"\n        );\n        anyhow::ensure!(\n            bar_type.spec().price_type == PriceType::Last,\n            \"Binance historical bars require LAST price type\"\n        );\n        anyhow::ensure!(\n            bar_type.spec().is_time_aggregated(),\n            \"Binance historical bars require time aggregation\"\n        );\n\n        get_runtime().spawn(async move {\n            let result = http.request_bars(bar_type, start, end, limit).await;\n\n            match result.context(\"failed to request bars from Binance\") {\n                Ok(bars) => {\n                    let response = DataResponse::Bars(BarsResponse::new(","sourceCodeStart":2338,"sourceCodeEnd":2374,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/spot/data.rs#L2338-L2374","documentation":"Historical Binance bars come only from Binance klines, which are built by the exchange itself. Nautilus distinguishes EXTERNAL aggregation (venue-built bars) from INTERNAL (locally aggregated); the adapter rejects BarsRequest bar types whose aggregation source is INTERNAL because the venue cannot serve history for a bar spec it never produced.","triggerScenarios":"Calling request_bars with a bar type string ending in -INTERNAL, e.g. 'ETHUSDT_BINANCE-5-MINUTE-LAST-INTERNAL'. The ensure! at spot/data.rs:2356 fails before the request task is spawned.","commonSituations":"Defaulting to AggregationSource::Internal when constructing BarType programmatically; requesting history for a bar type the strategy built for local aggregation; porting configs between adapters without checking the source suffix.","solutions":["Request the exchange-native bar type: suffix -EXTERNAL (AggregationSource::External), e.g. 'ETHUSDT_BINANCE-5-MINUTE-LAST-EXTERNAL'","For INTERNAL bars, subscribe to trades/quotes and let the local aggregator build them instead of requesting history","Check bar_type.aggregation_source() == AggregationSource::External before calling request_bars"],"exampleFix":"// before\nlet bar_type = BarType::from_str(\"ETHUSDT_BINANCE-5-MINUTE-LAST-INTERNAL\")?;\n\n// after: exchange-native klines\nlet bar_type = BarType::from_str(\"ETHUSDT_BINANCE-5-MINUTE-LAST-EXTERNAL\")?;","handlingStrategy":"validation","validationCode":"fn ensure_external(bar_type: &BarType) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        bar_type.aggregation_source() == AggregationSource::External,\n        \"historical Binance bars need aggregation source EXTERNAL, got {bar_type}\"\n    );\n    Ok(())\n}","typeGuard":"fn is_external_bar(bar_type: &BarType) -> bool {\n    bar_type.aggregation_source() == AggregationSource::External\n}","tryCatchPattern":null,"preventionTips":["When constructing BarType for venue history, always pass AggregationSource::External explicitly","Reserve -INTERNAL bar types for locally aggregated subscriptions","Log the bar type string before requesting history; the suffix is the first thing to check"],"tags":["binance","spot","bars","aggregation-source","validation"],"backgroundTag":"invalid-bar-specification","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}