nautechsystems/nautilus_trader · error
invalid price `{value}` at precision {precision}: {e}
Error message
invalid price `{value}` at precision {precision}: {e} What it means
parse_optional_price converts a Lighter decimal price into a Nautilus Price at a fixed precision using Price::from_decimal_dp. Zero prices are treated as 'no price' and return Ok(None); any non-zero value that cannot be represented exactly at the given precision (excess decimal places, out-of-range magnitude) produces this error wrapping the underlying failure.
Source
Thrown at crates/adapters/lighter/src/websocket/parse.rs:1202
return Ok(UnixNanos::default());
}
let millis = if timestamp <= UNIX_TIMESTAMP_SECONDS_MAX {
timestamp * 1_000
} else {
timestamp
};
parse_millis_to_nanos(millis as u64)
}
fn parse_optional_price(value: Decimal, precision: u8) -> anyhow::Result<Option<Price>> {
if value.is_zero() {
return Ok(None);
}
Price::from_decimal_dp(value, precision)
.map(Some)
.map_err(|e| anyhow::anyhow!("invalid price `{value}` at precision {precision}: {e}"))
}
fn lighter_fee_to_commission(
fee_ticks: Option<i32>,
currency: Currency,
) -> Result<Money, LighterCommissionError> {
let ticks = fee_ticks.unwrap_or(0);
let amount = Decimal::new(i64::from(ticks), FEE_DECIMALS);
Money::from_decimal(amount, currency).map_err(|e| LighterCommissionError::new(e.to_string()))
}
fn nautilus_order_side(side: LighterOrderSide) -> OrderSide {
match side {
LighterOrderSide::Buy => OrderSide::Buy,
LighterOrderSide::Sell => OrderSide::Sell,
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Round/quantize the Decimal to the target precision before calling: value.round_dp(precision), accepting the small quantization, or reject upstream if the difference is material.
- Verify the instrument's price precision used to compute the `precision` argument matches the exchange's current tick size; refresh the instrument if stale.
- Log the raw value and precision on failure to see whether the value or the precision is wrong.
- If Lighter genuinely emits finer prices after a market change, update the instrument definition in your catalog rather than hacking the parser.
Example fix
// before
Price::from_decimal_dp(value, precision)
.map(Some)
.map_err(|e| anyhow::anyhow!("invalid price `{value}` at precision {precision}: {e}"))
// after
let value = value.round_dp(u32::from(precision));
Price::from_decimal_dp(value, precision)
.map(Some)
.map_err(|e| anyhow::anyhow!("invalid price `{value}` at precision {precision}: {e}")) Defensive patterns
Strategy: validation
Validate before calling
fn fits_precision(value: Decimal, precision: u8) -> bool {
value.scale() <= u32::from(precision) && value.is_finite()
} Try / catch
match parse_optional_price(raw, precision) {
Ok(Some(p)) => p,
Ok(None) => return Ok(None),
Err(e) => { log::warn!("price {raw} unusable at precision {precision}: {e}"); return Ok(None); }
} Prevention
- Quantize exchange decimals to the instrument's precision before constructing Price.
- Refresh instrument definitions when the exchange changes tick size.
- Treat a failed price parse as a skip-with-warning for non-critical reports rather than a stream failure.
When it happens
Trigger: parse_ws_order_status_report or lighter_order_shape receives a non-zero Lighter price whose decimal representation does not fit the instrument's price precision (e.g. 0.123456 with precision 2), or a value beyond Price's representable range.
Common situations: Exchange changes tick size and emits prices finer than the locally configured precision; instrument registered with wrong precision; a synthetic/derived price (e.g. stop trigger computed elsewhere) carries more dp than allowed; test fixtures using arbitrary precision decimals.
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
- price precision {precision} exceeds maximum {MAX_DECIMALS}
- invalid Futures trade id {}: {e}
- Failed to parse '{field_name}' value '{value}' into Price: {
- Failed to create avg_px price: {e}
- invalid price `{value}`: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/22b29b9d3adc8a53.
Report an issue: GitHub.