nautechsystems/nautilus_trader · error

precision_from_scientific should return Some in strict mode

Error message

precision_from_scientific should return Some in strict mode

What it means

precision_from_str in crates/core/src/string/parsing.rs:122 computes decimal precision from a numeric string, and for strings containing 'e' it calls precision_from_scientific(&s, false, true) in strict mode, expecting Some. The expect panics with "precision_from_scientific should return Some in strict mode" when the scientific notation is so malformed that even strict parsing cannot extract an exponent (e.g. 'e' present but no numeric exponent follows).

Source

Thrown at crates/core/src/string/parsing.rs:122

}

/// Returns the decimal precision inferred from the given string.
///
/// For scientific notation (e.g., "1e-300", "1.5e-2"), the precision accounts
/// for both the mantissa's fractional digits and the signed exponent:
/// `max(0, fractional_digits - exponent)`, clamped to `u8::MAX` (255).
///
/// # Panics
///
/// Panics if the input string is malformed (e.g., "1e-" with no exponent value, or non-numeric
/// exponents like "1e-abc").
#[must_use]
pub fn precision_from_str(s: &str) -> u8 {
    let s = s.trim().to_ascii_lowercase();

    if s.contains('e') {
        return precision_from_scientific(&s, false, true)
            .expect("precision_from_scientific should return Some in strict mode");
    }

    if let Some((_, decimal_part)) = s.split_once('.') {
        clamp_precision_with_log(decimal_part.len(), "Decimal", &s)
    } else {
        0
    }
}

/// Returns the minimum increment precision inferred from the given string,
/// ignoring trailing zeros.
///
/// For scientific notation (e.g., "1e-300", "1.5e-2"), trailing zeros in the
/// mantissa are stripped before computing precision, matching the behavior of
/// [`precision_from_str`].
#[must_use]
pub fn min_increment_precision_from_str(s: &str) -> u8 {
    let s = s.trim().to_ascii_lowercase();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the input to well-formed scientific notation, e.g. "1.5e-8" instead of "1e" or "2.5e+".
  2. Pre-validate with a regex such as ^-?\d+(\.\d+)?[eE][+-]?\d+$ before calling precision_from_str.
  3. Correct the upstream producer (vendor feed, config generator) that emitted the truncated notation.
  4. If malformed values are expected in your pipeline, sanitize or reject them before this call rather than letting the strict-mode expect fire.

Example fix

// before
let p = precision_from_str("2.5e+");   // panics in strict mode
// after
let p = precision_from_str("2.5e-9");  // well-formed scientific notation
Defensive patterns

Strategy: validation

Validate before calling

import re
if 'e' in s.lower():
    assert re.fullmatch(r"\d+(\.\d+)?e[+-]?\d+", s.lower()), f"malformed scientific notation: {s!r}"
precision = precision_from_str(s)

Type guard

fn is_parseable_numeric(s: &str) -> bool {
    s.trim().parse::<f64>().is_ok()
}

Prevention

When it happens

Trigger: Calling precision_from_str with strings like "1e", "2.5e+", "e-", or "1.0Eexponent" — the 'e' check passes but scientific parsing cannot recover an exponent, so strict mode returns None and the expect fires.

Common situations: Config files or CSV feeds with truncated exponent fields ("1e" after a spreadsheet cut a column); regex-based string munging that dropped the exponent digits; hand-typed precision values.

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/0b15005c9250267e. Report an issue: GitHub.