{"record":{"id":"3b42080722046af8","repo":"nautechsystems/nautilus_trader","slug":"only-external-aggregation-is-supported","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/binance/src/futures/http/client.rs","lineNumber":2975,"sourceCode":"                )\n            })\n            .collect()\n    }\n\n    /// Requests bar (kline/candlestick) data for an instrument.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the bar type is not supported, instrument is not cached,\n    /// or the request fails.\n    pub async fn request_binance_bars(\n        &self,\n        bar_type: BarType,\n        start: Option<Timestamp>,\n        end: Option<Timestamp>,\n        limit: Option<u32>,\n    ) -> anyhow::Result<Vec<BinanceBar>> {\n        anyhow::ensure!(\n            bar_type.aggregation_source() == AggregationSource::External,\n            \"Only EXTERNAL aggregation is supported\"\n        );\n\n        let spec = bar_type.spec();\n        let step = spec.step.get();\n        let interval = match spec.aggregation {\n            BarAggregation::Second => {\n                anyhow::bail!(\"Binance Futures does not support second-level kline intervals\")\n            }\n            BarAggregation::Minute => format!(\"{step}m\"),\n            BarAggregation::Hour => format!(\"{step}h\"),\n            BarAggregation::Day => format!(\"{step}d\"),\n            BarAggregation::Week => format!(\"{step}w\"),\n            BarAggregation::Month => format!(\"{step}M\"),\n            a => anyhow::bail!(\"Binance Futures does not support {a:?} aggregation\"),\n        };\n","sourceCodeStart":2957,"sourceCodeEnd":2993,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/futures/http/client.rs#L2957-L2993","documentation":"Thrown by BinanceFuturesHttpClient::request_binance_bars when the BarType's aggregation_source is not AggregationSource::External. The method fetches venue-native klines, which only makes sense for externally-aggregated bars; internally-aggregated bar types are built by the local NautilusTrader aggregation engine from ticks, so requesting them from the venue is a category error the client rejects immediately.","triggerScenarios":"Calling request_binance_bars with a BarType parsed from a string like 'BTCUSDT.BINANCE_PERP-1-MINUTE-LAST-INTERNAL'; building a BarType with AggregationSource::Internal via the standard From<CompositePriceType> helpers and passing it to the HTTP client; generic historical-data loaders that forward any subscribed bar type to the venue request path.","commonSituations":"Strategies that subscribe to internal bars (e.g. for tick- or volume-aggregated synthetic bars) but reuse the same request path for historical backfill; misparsed bar type strings where the aggregation source suffix is wrong; confusion between the DataEngine's internal aggregation subscription route and the venue's kline endpoint.","solutions":["Use an External aggregation source in the BarType for venue kline requests (e.g. '...-1-MINUTE-LAST-EXTERNAL')","For internal aggregation, instead request the underlying historical ticks/bars and let the internal aggregator build the bars","Validate bar_type.aggregation_source() before dispatching to request_binance_bars"],"exampleFix":"// before\nlet bar_type: BarType = \"BTCUSDT.BINANCE_PERP-1-MINUTE-LAST-INTERNAL\".parse()?;\nlet bars = client.request_binance_bars(bar_type, start, end, None).await?;\n\n// after\nlet bar_type: BarType = \"BTCUSDT.BINANCE_PERP-1-MINUTE-LAST-EXTERNAL\".parse()?;\nlet bars = client.request_binance_bars(bar_type, start, end, None).await?;","handlingStrategy":"type-guard","validationCode":"if bar_type.aggregation_source() != AggregationSource::External {\n    anyhow::bail!(\"refusing venue request for {bar_type}: not EXTERNAL\");\n}","typeGuard":"fn is_venue_requestable(bar_type: &BarType) -> bool {\n    bar_type.aggregation_source() == AggregationSource::External\n}","tryCatchPattern":"Guard on aggregation_source before the call; on error, re-issue with an EXTERNAL bar type or redirect to the internal aggregation pipeline.","preventionTips":["Use -EXTERNAL suffixed bar type strings for venue klines","Route internal bar types to the DataEngine aggregator, not HTTP clients","Validate bar type strings at config parse time"],"tags":["binance","futures","bars","klines","aggregation","rust","nautilustrader"],"backgroundTag":"unsupported-bar-aggregation","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}