nautechsystems/nautilus_trader · error

Unsupported bar aggregation type: '{suffix}'

Error message

Unsupported bar aggregation type: '{suffix}'

What it means

parse_bar_spec converts Tardis bar spec strings like '1m', '100ticks', '5vol' into BarAggregation values. The suffix after the numeric step must be one of ms/s/m/ticks/vol; any other suffix triggers this bail, wrapped with 'Invalid bar spec' context.

Source

Thrown at crates/adapters/tardis/src/common/parse.rs:345

        .last()
        .ok_or_else(|| anyhow::anyhow!("Invalid bar spec: empty string"))?;
    let split_idx = last_part
        .chars()
        .position(|c| !c.is_ascii_digit())
        .ok_or_else(|| anyhow::anyhow!("Invalid bar spec: no aggregation suffix in '{value}'"))?;

    let (step_str, suffix) = last_part.split_at(split_idx);
    let step: usize = step_str
        .parse()
        .map_err(|e| anyhow::anyhow!("Invalid step in bar spec '{value}': {e}"))?;

    let aggregation = match suffix {
        "ms" => BarAggregation::Millisecond,
        "s" => BarAggregation::Second,
        "m" => BarAggregation::Minute,
        "ticks" => BarAggregation::Tick,
        "vol" => BarAggregation::Volume,
        _ => anyhow::bail!("Unsupported bar aggregation type: '{suffix}'"),
    };

    parse_canonical_bar_spec(step, aggregation)
        .with_context(|| format!("Invalid bar spec '{value}'"))
}

fn parse_canonical_bar_spec(
    step: usize,
    aggregation: BarAggregation,
) -> anyhow::Result<BarSpecification> {
    match aggregation {
        BarAggregation::Millisecond if step.is_multiple_of(1000) => {
            parse_canonical_bar_spec(step / 1000, BarAggregation::Second)
        }
        BarAggregation::Second if step.is_multiple_of(60) => {
            parse_canonical_bar_spec(step / 60, BarAggregation::Minute)
        }
        BarAggregation::Minute if step.is_multiple_of(60) => {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use only supported suffixes: ms, s, m, ticks, vol (e.g. '1m', '60s', '100ticks', '5vol')
  2. Convert unsupported aggregations (hour/day) yourself into supported units, e.g. 1h -> 60m
  3. Check the input string for typos or swapped order (step must come first: '5m', not 'm5')
  4. If hourly/daily Tardis bars are needed, request support or aggregate upstream data manually

Example fix

// before
let spec = parse_bar_spec("1h")?; // bail: Unsupported bar aggregation type: 'h'
// after
let spec = parse_bar_spec("60m")?; // equivalent, supported suffix
Defensive patterns

Strategy: validation

Validate before calling

fn is_supported_bar_spec(spec: &str) -> bool {
    let suffix = spec.trim_start_matches(|c: char| c.is_ascii_digit());
    matches!(suffix, "ms" | "s" | "m" | "ticks" | "vol")
}
// call before parse_bar_spec
assert!(is_supported_bar_spec("60m"));

Prevention

When it happens

Trigger: Calling parse_bar_spec (or parse_bar_msg) with a bar spec string whose aggregation suffix is not one of ms, s, m, ticks, vol — e.g. '1h', '5d', '10count' or a malformed spec like 'm1'.

Common situations: Tardis dataset uses an aggregation NautilusTrader does not map (hourly/daily bars); typos in bar spec strings in config; passing Tardis-specific strings that use unsupported units.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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