{"record":{"id":"0695e5100f90127b","repo":"nautechsystems/nautilus_trader","slug":"invalid-bar-spec-no-aggregation-suffix-in-value","errorCode":null,"errorMessage":"Invalid bar spec: no aggregation suffix in '{value}'","messagePattern":"Invalid bar spec: no aggregation suffix in '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/common/parse.rs","lineNumber":332,"sourceCode":"    }\n}\n\n/// Parses a Nautilus bar specification from the given Tardis string `value`.\n///\n/// The [`PriceType`] is always `LAST` for Tardis trade bars.\n///\n/// # Errors\n///\n/// Returns an error if the specification format is invalid or if the aggregation suffix is unsupported.\npub fn parse_bar_spec(value: &str) -> anyhow::Result<BarSpecification> {\n    let parts: Vec<&str> = value.split('_').collect();\n    let last_part = parts\n        .last()\n        .ok_or_else(|| anyhow::anyhow!(\"Invalid bar spec: empty string\"))?;\n    let split_idx = last_part\n        .chars()\n        .position(|c| !c.is_ascii_digit())\n        .ok_or_else(|| anyhow::anyhow!(\"Invalid bar spec: no aggregation suffix in '{value}'\"))?;\n\n    let (step_str, suffix) = last_part.split_at(split_idx);\n    let step: usize = step_str\n        .parse()\n        .map_err(|e| anyhow::anyhow!(\"Invalid step in bar spec '{value}': {e}\"))?;\n\n    let aggregation = match suffix {\n        \"ms\" => BarAggregation::Millisecond,\n        \"s\" => BarAggregation::Second,\n        \"m\" => BarAggregation::Minute,\n        \"ticks\" => BarAggregation::Tick,\n        \"vol\" => BarAggregation::Volume,\n        _ => anyhow::bail!(\"Unsupported bar aggregation type: '{suffix}'\"),\n    };\n\n    parse_canonical_bar_spec(step, aggregation)\n        .with_context(|| format!(\"Invalid bar spec '{value}'\"))\n}","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/common/parse.rs#L314-L350","documentation":"parse_bar_spec expects the last '_' separated part to begin with a numeric step (e.g. \"1m\", \"100ticks\"). If no leading ASCII digits are found in that part, there is no aggregation step, and the function rejects the value with this error naming the original spec string.","triggerScenarios":"Calling parse_bar_spec with a spec whose final segment lacks a leading number: \"m\" (e.g. \"BTCUSD_m\" with no step), \"minute\", \"1-MINUTE\" if the '_' split leaves a non-numeric tail, or a symbol accidentally used as a bar spec.","commonSituations":"Confusing Tardis bar spec syntax with Nautilus BarSpecification strings; a Tardis symbol suffix like \"_m\" (month futures) being mistaken for a bar spec; typos in subscription configuration.","solutions":["Check the spec string printed in the error — the final '_' part must start with digits, e.g. \"..._1m\", \"..._100ticks\"","Convert Nautilus-style specs (\"1-MINUTE\") to the Tardis expected format before parsing","Ensure futures symbols with month suffixes are not routed into parse_bar_spec","Validate bar specs at config load to catch the typo early"],"exampleFix":"// before\nlet bar = parse_bar_spec(\"1-MINUTE\")?; // no numeric step in last part\n// after: Tardis-style spec\nlet bar = parse_bar_spec(\"BTCUSD_1m\")?; // step '1' + suffix 'm'","handlingStrategy":"validation","validationCode":"fn has_numeric_step(value: &str) -> bool {\n    value.rsplit('_').next()\n        .map(|last| last.chars().next().map(|c| c.is_ascii_digit()).unwrap_or(false))\n        .unwrap_or(false)\n}","typeGuard":null,"tryCatchPattern":"match parse_bar_spec(spec) {\n    Ok(bar) => /* proceed */,\n    Err(e) if e.to_string().contains(\"no aggregation suffix\") => {\n        log::error!(\"malformed bar spec '{spec}': expected '<step><suffix>', e.g. '1m'\");\n        return Err(e.into());\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Use Tardis bar spec syntax: step digits + suffix, e.g. '1m', '100ticks'","Do not route instrument/futures symbols (with month suffixes) into parse_bar_spec","Validate spec format at config load"],"tags":["tardis","bar-spec","parsing","format"],"backgroundTag":"invalid-argument-format","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"}