nautechsystems/nautilus_trader · critical

Raw value exceeds PriceRaw range in Price::from_mantissa_exp

Error message

Raw value exceeds PriceRaw range in Price::from_mantissa_exponent

What it means

After a successful i128 conversion, from_mantissa_exponent narrows the i128 raw value to PriceRaw (the platform's price storage integer). If the i128 value does not fit in PriceRaw, try_into().expect panics. This is a narrower-range overflow than the i128 overflow error: the value fits i128 but exceeds PriceRaw's bounds, which the following assert also documents.

Source

Thrown at crates/model/src/types/price.rs:533

    /// Panics if the resulting raw value exceeds [`PRICE_RAW_MAX`] or [`PRICE_RAW_MIN`].
    #[must_use]
    pub fn from_mantissa_exponent(mantissa: i64, exponent: i8, precision: u8) -> Self {
        check_fixed_precision(precision).expect_display(FAILED);

        if mantissa == 0 {
            return Self { raw: 0, precision };
        }

        let raw_i128 = mantissa_exponent_to_fixed_i128(i128::from(mantissa), exponent, precision)
            .expect("Overflow in Price::from_mantissa_exponent");

        #[allow(
            clippy::useless_conversion,
            reason = "i128 to PriceRaw is real when not high-precision"
        )]
        let raw: PriceRaw = raw_i128
            .try_into()
            .expect("Raw value exceeds PriceRaw range in Price::from_mantissa_exponent");
        assert!(
            raw >= PRICE_RAW_MIN && raw <= PRICE_RAW_MAX,
            "`raw` value {raw} exceeded bounds [{PRICE_RAW_MIN}, {PRICE_RAW_MAX}] for Price"
        );

        Self { raw, precision }
    }

    /// Checked variant of [`Price::from_mantissa_exponent`].
    ///
    /// # Errors
    ///
    /// Returns an error if the precision is invalid or the resulting raw value
    /// exceeds the `PriceRaw` bounds.
    pub fn from_mantissa_exponent_checked(
        mantissa: i64,
        exponent: i8,
        precision: u8,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Lower the effective value or raise precision so the fixed-point raw falls within [PRICE_RAW_MIN, PRICE_RAW_MAX].
  2. Check PRICE_RAW_MAX before constructing and reject/clamp the offending tick instead of constructing.
  3. Use the high-precision feature/build so PriceRaw is wider if your instrument range legitimately needs it.
  4. Sanitize upstream data: reject prices beyond the instrument's defined price bounds before conversion.

Example fix

// before
let price = Price::from_mantissa_exponent(i64::MAX, 20, 9); // raw exceeds PriceRaw range
// after
let price = Price::from_mantissa_exponent(12_345, 5, 9); // 1,234,500,000,000,000 fits PriceRaw
Defensive patterns

Strategy: validation

Validate before calling

// Rust
fn price_raw_fits(raw: i128) -> bool {
    raw >= i128::from(PRICE_RAW_MIN) && raw <= i128::from(PRICE_RAW_MAX)
}

Type guard

fn to_price_raw(raw: i128) -> Option<PriceRaw> {
    PriceRaw::try_from(raw).ok().filter(|r| (PRICE_RAW_MIN..=PRICE_RAW_MAX).contains(r))
}

Prevention

When it happens

Trigger: Price::from_mantissa_exponent with mantissa/exponent whose fixed-point raw value fits i128 but is greater than PRICE_RAW_MAX (or below PRICE_RAW_MIN), typically huge mantissas with large positive exponents under a non-high-precision PriceRaw build.

Common situations: Loading prices from a venue denominated in minimal units with a large exponent mismatch; config mistakes where precision is lower than needed, inflating the fixed-point raw; unit tests reusing quantity-scale numbers as prices.

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/88ce32d1bb8c479a. Report an issue: GitHub.