nautechsystems/nautilus_trader · error

Bybit does not support {aggregation:?} bars

Error message

Bybit does not support {aggregation:?} bars

What it means

The catch-all branch of bar_spec_to_bybit_interval rejects any BarAggregation the Bybit adapter does not map to a kline interval at all. Only Minute, Hour, Day, Week and Month are supported; aggregations like Tick or Volume cannot be requested from Bybit's REST kline endpoints and raise this anyhow error.

Source

Thrown at crates/adapters/bybit/src/common/parse.rs:328

            if step != 1 {
                anyhow::bail!("Bybit only supports 1 DAY interval bars");
            }
            Ok(BybitKlineInterval::Day1)
        }
        BarAggregation::Week => {
            if step != 1 {
                anyhow::bail!("Bybit only supports 1 WEEK interval bars");
            }
            Ok(BybitKlineInterval::Week1)
        }
        BarAggregation::Month => {
            if step != 1 {
                anyhow::bail!("Bybit only supports 1 MONTH interval bars");
            }
            Ok(BybitKlineInterval::Month1)
        }
        _ => {
            anyhow::bail!("Bybit does not support {aggregation:?} bars");
        }
    }
}

fn default_margin() -> Decimal {
    Decimal::new(1, 1)
}

/// Parses a spot instrument definition returned by Bybit into a Nautilus currency pair.
///
/// # Panics
///
/// Panics if the constructed instrument fails validation.
pub fn parse_spot_instrument(
    definition: &BybitInstrumentSpot,
    fee_rate: &BybitFeeRate,
    ts_event: UnixNanos,
    ts_init: UnixNanos,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Switch the bar spec to a time aggregation (Minute/Hour/Day/Week/Month) that Bybit supports
  2. Use the nautilus internal aggregation engine: subscribe with internal aggregation so ticks/trades are aggregated locally instead of requesting Bybit klines
  3. Aggregate raw trades locally into Tick/Volume bars in your strategy

Example fix

// before
let bar_spec = BarSpecification::new(100, BarAggregation::Tick, PriceType::Last);
// after (internal aggregation instead of Bybit kline request)
let bar_spec = BarSpecification::new(1, BarAggregation::Minute, PriceType::Last);
Defensive patterns

Strategy: validation

Validate before calling

fn supports_aggregation(a: BarAggregation) -> bool {
    matches!(a, BarAggregation::Minute | BarAggregation::Hour | BarAggregation::Day | BarAggregation::Week | BarAggregation::Month)
}

Type guard

fn is_time_aggregation(a: BarAggregation) -> bool {
    matches!(a, BarAggregation::Minute | BarAggregation::Hour | BarAggregation::Day | BarAggregation::Week | BarAggregation::Month)
}

Try / catch

if let Err(e) = request_bars(...).await {
    log::warn!("{e}; switching to internal tick aggregation");
    subscribe_with_internal_aggregation(...)?;
}

Prevention

When it happens

Trigger: Calling request_bars with a BarSpecification whose aggregation is Tick, Volume, Value, DollarValue or any other non-time aggregation (e.g. 100-TICK bars or 1000-VOLUME bars via the Bybit adapter).

Common situations: Subscribing to tick- or volume-aggregated bars assuming the exchange provides them; using a bar spec that works with internal aggregators but not via the direct Bybit historical-request path.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/34aa3d49924c6b42. Report an issue: GitHub.