nautechsystems/nautilus_trader · error
invalid price `{value}`: {e}
Error message
invalid price `{value}`: {e} What it means
parse_price first parses the input string with rust_decimal's Decimal::from_str. This error means the string is not a valid decimal number (bad characters, empty string, multiple dots, scientific notation beyond rust_decimal's acceptance, etc.), so no Price can be constructed. The raw value is included in the message for diagnosis.
Source
Thrown at crates/adapters/lighter/src/common/parse.rs:97
let decimal = Decimal::new(ticks, u32::from(decimals));
Quantity::from_decimal_dp(decimal, decimals).map_err(|e| {
anyhow::anyhow!("Quantity overflow for ticks={ticks}, decimals={decimals}: {e}")
})
}
/// Converts a decimal string into a Nautilus [`Price`] at the requested precision.
///
/// # Errors
///
/// Returns an error if the string is not a decimal, if `precision` exceeds
/// [`MAX_DECIMALS`], or if the resulting value is out of range.
pub fn parse_price(value: &str, precision: u8) -> anyhow::Result<Price> {
anyhow::ensure!(
precision <= MAX_DECIMALS,
"price precision {precision} exceeds maximum {MAX_DECIMALS}",
);
let decimal =
Decimal::from_str(value).map_err(|e| anyhow::anyhow!("invalid price `{value}`: {e}"))?;
Price::from_decimal_dp(decimal, precision)
.map_err(|e| anyhow::anyhow!("invalid price `{value}` at precision {precision}: {e}"))
}
/// Converts a decimal string into a non-negative Nautilus [`Quantity`].
///
/// Zero is allowed because Lighter sends zero-size book levels to delete
/// existing orders.
///
/// # Errors
///
/// Returns an error if the string is not a decimal, if `precision` exceeds
/// [`MAX_DECIMALS`], if the value is negative, or if the resulting quantity
/// is out of range.
pub fn parse_quantity(value: &str, precision: u8) -> anyhow::Result<Quantity> {
anyhow::ensure!(
precision <= MAX_DECIMALS,
"size precision {precision} exceeds maximum {MAX_DECIMALS}",View on GitHub (pinned to 18893faf8b)
Solutions
- Validate/normalize the string first: trim whitespace, strip currency symbols and thousands separators, and replace locale decimal commas with dots.
- Ensure the field is the raw decimal string as sent by Lighter's API (e.g. "123.45"), not a human-formatted rendering.
- If the value arrives as JSON, deserialize it with the adapter's deserialize_decimal helper and use price_from_decimal instead of string parsing.
- Log the offending value from the error message and add a unit test pinning the expected wire format.
Example fix
// before
let price = parse_price("1,234.50 USD", precision)?;
// after
let normalized = raw.trim().replace(",", "");
let price = parse_price(&normalized, precision)?; Defensive patterns
Strategy: try-catch
Validate before calling
fn is_plain_decimal(s: &str) -> bool {
let s = s.trim();
!s.is_empty()
&& s.chars().all(|c| c.is_ascii_digit() || c == '.' || c == '-' || c == '+')
&& s.matches('.').count() <= 1
} Try / catch
match parse_price(raw, precision) {
Ok(p) => p,
Err(e) if e.to_string().starts_with("invalid price") => {
tracing::warn!(raw = %raw, "unparseable price string; skipping");
return Ok(None);
}
Err(e) => return Err(e.into()),
} Prevention
- Pass the raw wire string untouched — no display formatting, locale separators, or currency suffixes
- Trim whitespace and strip annotations before parsing user- or config-sourced strings
- Prefer deserialize_decimal + price_from_decimal over string parsing when the value arrives as JSON numeric data
- Pin the expected wire format with a unit test on the parser
When it happens
Trigger: Calling parse_price with a string that Decimal::from_str cannot parse — e.g. "", "N/A", "1,234.5" (thousands separator), "0x1F", "1.2.3", or an already-formatted/annotated string like "123.45 USD".
Common situations: Feeding a display-formatted price into the parser; locale-formatted numbers with comma decimal separators; upstream payloads where a numeric field was serialized as a localized or annotated string; stringly-typed config values for limit prices.
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
- invalid quantity `{value}`: {e}
- invalid signed E18 integer for {field}: {value}
- invalid {field}='{raw}': {e}
- Failed to parse '{field_name}' value '{value}' into Decimal:
- Failed to convert avg fill price to Decimal: {converted_avg_
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1bf6f26ec57f74fa.
Report an issue: GitHub.