nautechsystems/nautilus_trader · error

size decimals {decimals} exceeds maximum {MAX_DECIMALS}

Error message

size decimals {decimals} exceeds maximum {MAX_DECIMALS}

What it means

`parse_quantity_from_ticks` converts an integer tick count and decimal count into a Nautilus `Quantity`. It fails if `decimals` exceeds `MAX_DECIMALS`; this specific error indicates the size precision requested is more granular than the supported maximum (additional errors exist for negative ticks and range overflow).

Source

Thrown at crates/adapters/lighter/src/common/parse.rs:74

}

/// Converts a Lighter base-amount tick count into a Nautilus [`Quantity`].
///
/// Order sizes on the wire are signed `i64` multiples of `10^-decimals`
/// base-asset units. Nautilus [`Quantity`] is non-negative, so a negative
/// `ticks` value is rejected: callers (e.g. position parsers) extract the
/// sign separately before invoking this parser.
///
/// Conversion routes through [`Decimal`] and [`Quantity::from_decimal_dp`]
/// so out-of-range tick counts return an error rather than panicking inside
/// the unchecked mantissa-exponent constructor.
///
/// # Errors
///
/// Returns an error if `decimals` exceeds [`MAX_DECIMALS`], if `ticks` is
/// negative, or if the resulting value exceeds the [`Quantity`] range.
pub fn parse_quantity_from_ticks(ticks: i64, decimals: u8) -> anyhow::Result<Quantity> {
    anyhow::ensure!(
        decimals <= MAX_DECIMALS,
        "size decimals {decimals} exceeds maximum {MAX_DECIMALS}",
    );
    anyhow::ensure!(ticks >= 0, "negative tick count {ticks} for Quantity");
    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!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the market's size precision is <= MAX_DECIMALS before parsing.
  2. Round/quantize the size to a supported precision consistent with the instrument's `size_increment`.
  3. Check for swapped arguments (e.g. passing price decimals where size decimals are expected).

Example fix

// before
let qty = parse_quantity_from_ticks(ticks, 20)?;
// after
ensure!(decimals <= MAX_DECIMALS, "size precision not supported");
let qty = parse_quantity_from_ticks(ticks, decimals)?;
Defensive patterns

Strategy: validation

Validate before calling

if decimals > lighter::parse::MAX_DECIMALS {
    return Err(anyhow!("size precision {decimals} unsupported"));
}
if ticks < 0 {
    return Err(anyhow!("negative ticks {ticks}"));
}

Type guard

fn size_precision_supported(d: u8) -> bool { d <= lighter::parse::MAX_DECIMALS }

Try / catch

let qty = parse_quantity_from_ticks(ticks, decimals)
    .map_err(|e| { eprintln!("quantity parse failed: {e}"); e })?;

Prevention

When it happens

Trigger: Calling `parse_quantity_from_ticks(ticks, decimals)` with `decimals > MAX_DECIMALS`, e.g. parsing a Lighter instrument's size precision that exceeds the adapter limit.

Common situations: Markets configured with very high quantity precision; reusing decimal constants from another venue's instrument definitions; copy-paste of price decimals into size decimals.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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