nautechsystems/nautilus_trader · error
Invalid scientific notation exponent '{exponent}': must be a
Error message
Invalid scientific notation exponent '{exponent}': must be a valid number What it means
`precision_from_v1_str` is a temporary legacy parser that infers a price-precision u8 from v1 source text. When the text uses scientific notation (`e-`), the exponent substring must parse as a number; if it contains non-digit characters the parser panics with this message. It protects against silently mapping malformed exponents (like `1e-abc`) to a wrong precision. The panic is converted to an abort via `abort_on_panic` in the FFI entry `precision_from_cstr`.
Source
Thrown at crates/core/src/ffi/parsing.rs:214
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)| {
u8::try_from(decimal.len()).unwrap_or(u8::MAX)
})
}
/// Return a `bool` value from the given `u8`.
#[must_use]
pub const fn u8_as_bool(value: u8) -> bool {
value != 0
}
#[cfg(test)]
mod tests {
use std::ffi::CString;
use rstest::rstest;View on GitHub (pinned to 18893faf8b)
Solutions
- Correct the source string so the exponent is all digits (e.g. `1.5e-6`).
- Sanitize/validate numeric strings on the caller side before crossing the FFI boundary.
- Convert the value to plain decimal notation instead of scientific notation when generating v1 data.
- Pre-validate with an equivalent parser, since `abort_on_panic` turns the panic into a process abort.
Example fix
// before (data) price_increment = "1e-5x" // after price_increment = "1e-5" // or "0.00001"
Defensive patterns
Strategy: validation
Validate before calling
// Validate before crossing the FFI boundary
fn is_v1_numeric(s: &str) -> bool {
let s = s.trim().to_ascii_lowercase();
if let Some(idx) = s.find("e-") {
let exp = &s[idx + 2..];
return !exp.is_empty() && exp.chars().all(|c| c.is_ascii_digit());
}
true
} Type guard
fn valid_exponent(s: &str) -> bool {
s.split_once("e-").map_or(true, |(_, exp)| !exp.is_empty() && exp.chars().all(|c| c.is_ascii_digit()))
} Prevention
- Sanitize numeric strings from legacy v1 data before FFI calls
- Normalize scientific notation to plain decimals at the data source
- Remember `abort_on_panic` turns this panic into a process abort — validate early
- Reject strings with locale artifacts (commas, units) before parsing
When it happens
Trigger: Passing a C string price/increment like `"1.5e-XY"` or `"2e-1_0"` (exponent with non-digit chars) to `precision_from_cstr`; only strings containing `e-` with a garbage exponent reach the panic — plain decimals or missing/empty exponents panic earlier with different messages.
Common situations: Feeding locale-mangled numbers (thousands separators, letters) from legacy v1 config or CSV data into the FFI boundary; hand-written adapter configs where an increment was typed incorrectly; truncation of a number string mid-exponent.
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
- C string contains invalid JSON
- C string JSON must be an array of strings
- Invalid scientific notation format: missing exponent after '
- invalid `AggressorSide` enum string value, was '{value}'
- invalid `AssetClass` enum string value, was '{value}'
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/be90f1b016f053a4.
Report an issue: GitHub.