nautechsystems/nautilus_trader · error

Invalid scientific notation format: missing exponent after '

Error message

Invalid scientific notation format: missing exponent after 'e-'

What it means

precision_from_v1_str in crates/core/src/ffi/parsing.rs:199 parses a decimal-precision value from a string that may use scientific notation. When the string contains 'e-', it splits on that token and unwraps the tail with expect; if no text follows 'e-' (or the split somehow yields nothing), the expect panics with "Invalid scientific notation format: missing exponent after 'e-'". It exists to guard an invariant the surrounding code assumes when the 'e-' token is present.

Source

Thrown at crates/core/src/ffi/parsing.rs:199

#[unsafe(no_mangle)]
pub unsafe extern "C" fn min_increment_precision_from_cstr(ptr: *const c_char) -> u8 {
    abort_on_panic(|| {
        assert!(!ptr.is_null(), "`ptr` was NULL");
        // SAFETY: Caller guarantees ptr is valid per function contract
        let s = unsafe { cstr_as_str(ptr) };
        min_increment_precision_from_str(s)
    })
}

// TODO: Remove this temporary parser when v1 drops its legacy source-text precision contract
fn precision_from_v1_str(value: &str) -> u8 {
    let value = value.trim().to_ascii_lowercase();

    if value.contains("e-") {
        let exponent = value
            .split("e-")
            .nth(1)
            .expect("Invalid scientific notation format: missing exponent after 'e-'");

        if let Ok(exponent) = exponent.parse::<u64>() {
            return u8::try_from(exponent).unwrap_or(u8::MAX);
        }

        assert!(
            !exponent.is_empty(),
            "Invalid scientific notation format: missing exponent after 'e-'"
        );

        if exponent.chars().all(|c| c.is_ascii_digit()) {
            return u8::MAX;
        }

        panic!("Invalid scientific notation exponent '{exponent}': must be a valid number");
    }

    value.split_once('.').map_or(0, |(_, decimal)| {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the input string so the exponent digits follow 'e-' (e.g. "1.5e-8" instead of "1.5e-").
  2. Validate the numeric string with a regex like ^\d+(\.\d+)?[eE]-?\d+$ before passing it to precision_from_cstr.
  3. If the value comes from a config file or vendor feed, correct the source value at its origin.
  4. Catch it in dev by unit-testing your string-producer path with precision_from_str to surface malformed notation early.

Example fix

// before
let precision = precision_from_cstr(cstr_from("1.5e-"));   // panics
// after
let precision = precision_from_cstr(cstr_from("1.5e-8"));  // exponent digits present
Defensive patterns

Strategy: validation

Validate before calling

# Python caller
import re
SCI = re.compile(r"^\d+(\.\d+)?[eE]-\d+$")
assert SCI.match(value), f"malformed scientific notation: {value!r}"
precision_from_cstr(value.encode())

Type guard

def is_valid_scientific(value: str) -> bool:
    import re
    return bool(re.fullmatch(r"\d+(\.\d+)?[eE]-?\d+", value))

Prevention

When it happens

Trigger: Calling precision_from_cstr with a string like "1.5e-" or "0.00012E-" (trailing minus with no digits) — the contains("e-") check matches but split("e-").nth(1) yields an empty/missing segment.

Common situations: Hand-edited instrument config files with truncated scientific notation; a data vendor emitting malformed price precision strings like "1e-"; copy-paste errors where exponent digits were cut off.

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