{"record":{"id":"1b7d3ab6fb0a9aaa","repo":"nautechsystems/nautilus_trader","slug":"invalid-step-in-bar-spec-value-e","errorCode":null,"errorMessage":"Invalid step in bar spec '{value}': {e}","messagePattern":"Invalid step in bar spec '(.+?)': (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/tardis/src/common/parse.rs","lineNumber":337,"sourceCode":"/// 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}\n\nfn parse_canonical_bar_spec(\n    step: usize,\n    aggregation: BarAggregation,\n) -> anyhow::Result<BarSpecification> {","sourceCodeStart":319,"sourceCodeEnd":355,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/tardis/src/common/parse.rs#L319-L355","documentation":"After extracting the leading digit run from the last part of a bar spec, parse_bar_spec parses it as usize. If that parse fails (e.g. a number too large for usize, or digits interleaved with later characters) the error wraps the std ParseIntError with the offending spec value.","triggerScenarios":"Calling parse_bar_spec with a step that overflows usize (e.g. \"99999999999999999999m\") or a malformed step where parse cannot handle the extracted digit string.","commonSituations":"Corrupted config values with absurd aggregation steps; a hand-typed bar spec with a typo in the numeric portion; generated specs from a template with an unbounded substitution.","solutions":["Check the spec value in the error message — the step must fit in usize and be a plain digit run","Use a realistic aggregation step (1, 5, 60, 100...) in your bar spec","Bound/validate the step value at config load before calling parse_bar_spec","If steps come from user input, clamp to supported aggregation ranges"],"exampleFix":"// before\nlet bar = parse_bar_spec(\"99999999999999999999m\")?; // usize overflow\n// after: validate step first\nlet step: u64 = step_str.parse()?;\nanyhow::ensure!(step <= 86_400, \"step too large\");\nlet bar = parse_bar_spec(&format!(\"{step}m\"))?;","handlingStrategy":"validation","validationCode":"fn step_in_range(value: &str) -> bool {\n    value.rsplit('_').next()\n        .and_then(|last| last.chars().position(|c| !c.is_ascii_digit()).map(|i| &last[..i]))\n        .and_then(|s| s.parse::<u64>().ok())\n        .map(|step| step > 0 && step <= 86_400)\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(\"Invalid step\") => {\n        log::error!(\"unparseable step in '{spec}'\");\n        return Err(e.into());\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Keep aggregation steps small and realistic (<= 86400)","Clamp template-generated steps to supported ranges","Validate the numeric portion before calling parse_bar_spec"],"tags":["tardis","bar-spec","parsing","integer-overflow"],"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"}