{"record":{"id":"c757b15f07d49d58","repo":"nautechsystems/nautilus_trader","slug":"only-external-aggregation-is-supported-c757b1","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/coinbase/src/common/parse.rs","lineNumber":125,"sourceCode":"/// # Errors\n///\n/// Returns an error when the nanosecond value is outside the Jiff timestamp range.\npub fn format_rfc3339_from_nanos(ts: UnixNanos) -> anyhow::Result<String> {\n    Ok(ts\n        .to_datetime_utc()\n        .display_with_offset(Offset::UTC)\n        .to_string())\n}\n\n/// Converts a Nautilus [`BarType`] to a [`CoinbaseGranularity`].\n///\n/// # Errors\n///\n/// Returns an error if the bar type uses an unsupported aggregation or step value.\npub fn bar_type_to_granularity(bar_type: &BarType) -> anyhow::Result<CoinbaseGranularity> {\n    let spec = bar_type.spec();\n\n    anyhow::ensure!(\n        bar_type.aggregation_source() == AggregationSource::External,\n        \"Only EXTERNAL aggregation is supported\"\n    );\n\n    let step = spec.step.get();\n\n    match spec.aggregation {\n        BarAggregation::Minute => match step {\n            1 => Ok(CoinbaseGranularity::OneMinute),\n            5 => Ok(CoinbaseGranularity::FiveMinute),\n            15 => Ok(CoinbaseGranularity::FifteenMinute),\n            30 => Ok(CoinbaseGranularity::ThirtyMinute),\n            _ => anyhow::bail!(\"Unsupported minute step: {step}\"),\n        },\n        BarAggregation::Hour => match step {\n            1 => Ok(CoinbaseGranularity::OneHour),\n            2 => Ok(CoinbaseGranularity::TwoHour),\n            6 => Ok(CoinbaseGranularity::SixHour),","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/coinbase/src/common/parse.rs#L107-L143","documentation":"Coinbase bar requests must use bars aggregated externally (by the exchange), not internally by Nautilus. bar_type_to_granularity checks the bar type's aggregation source and raises this error for INTERNAL aggregation.","triggerScenarios":"Calling request_bars (or anything using bar_type_to_granularity) with a BarType whose aggregation_source is AggregationSource::Internal, e.g. BarType.from_str(\"BTC-USD.COINBASE-1-MINUTE-INTERNAL\").","commonSituations":"Constructing bar types with the default/internal aggregation source and then trying to fetch historical bars from Coinbase; copying bar type strings between venues without flipping the source.","solutions":["Use an EXTERNAL aggregation source bar type: 'BTC-USD.COINBASE-1-MINUTE-EXTERNAL'","In Python, create the bar type with BarType.from_str(...-EXTERNAL) or aggregation_source=AggregationSource.EXTERNAL","Aggregate internally yourself if you must use INTERNAL bars instead of requesting from Coinbase"],"exampleFix":"# before\nbar_type = BarType.from_str(\"BTC-USD.COINBASE-1-MINUTE-INTERNAL\")\nclient.request_bars(bar_type)\n# after\nbar_type = BarType.from_str(\"BTC-USD.COINBASE-1-MINUTE-EXTERNAL\")\nclient.request_bars(bar_type)","handlingStrategy":"validation","validationCode":"if bar_type.aggregation_source != AggregationSource.EXTERNAL:\n    bar_type = BarType.from_str(str(bar_type).replace('-INTERNAL', '-EXTERNAL'))","typeGuard":null,"tryCatchPattern":"try:\n    client.request_bars(bar_type)\nexcept ValueError as e:\n    if 'Only EXTERNAL aggregation' in str(e):\n        client.request_bars(to_external(bar_type))","preventionTips":["Always build venue-fetchable bar types with -EXTERNAL","Keep a helper that converts internal bar types to external before historical requests","Document that Coinbase history endpoints only serve exchange-aggregated bars"],"tags":["rust","coinbase","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"}