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

  1. Validate/normalize the string first: trim whitespace, strip currency symbols and thousands separators, and replace locale decimal commas with dots.
  2. Ensure the field is the raw decimal string as sent by Lighter's API (e.g. "123.45"), not a human-formatted rendering.
  3. If the value arrives as JSON, deserialize it with the adapter's deserialize_decimal helper and use price_from_decimal instead of string parsing.
  4. 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

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/1bf6f26ec57f74fa. Report an issue: GitHub.