nautechsystems/nautilus_trader · error
Whole raw quantity must fit in Decimal
Error message
Whole raw quantity must fit in Decimal
What it means
Quantity::raw_as_decimal splits a raw fixed-point quantity into whole and fractional parts for Decimal conversion; the whole part (raw / FIXED_SCALAR_RAW) is narrowed to i128 with try_from and expect. If the whole component cannot fit in i128 (only possible when QuantityRaw is u128 in high-precision builds), this panics.
Source
Thrown at crates/model/src/types/quantity.rs:443
// because our quantity constraints ensure the maximum raw value times the scaling
// factor cannot exceed i128::MAX (high-precision) or i64::MAX (standard-precision).
#[allow(
clippy::unnecessary_cast,
clippy::cast_lossless,
reason = "cast is real when QuantityRaw is u64, no-op when u128"
)]
scaled_raw_to_decimal(rescaled_raw as i128, self.precision)
}
/// Returns a raw fixed-point quantity as a `Decimal`.
#[must_use]
#[allow(
clippy::unnecessary_fallible_conversions,
reason = "try_from is infallible when QuantityRaw is u64, fallible when u128"
)]
pub(crate) fn raw_as_decimal(raw: QuantityRaw) -> Decimal {
let whole =
i128::try_from(raw / FIXED_SCALAR_RAW).expect("Whole raw quantity must fit in Decimal");
let fractional = i128::try_from(raw % FIXED_SCALAR_RAW)
.expect("Fractional raw quantity must fit in Decimal");
Decimal::from(whole) + Decimal::from_i128_with_scale(fractional, u32::from(FIXED_PRECISION))
}
/// Returns a formatted string representation of this instance.
#[must_use]
pub fn to_formatted_string(&self) -> String {
format!("{self}").separate_with_underscores()
}
/// Creates a new [`Quantity`] from a `Decimal` value with specified precision.
///
/// Uses pure integer arithmetic on the Decimal's mantissa and scale for fast conversion.
/// The value is rounded to the specified precision using banker's rounding (round half to even).
///
/// # ErrorsView on GitHub (pinned to 18893faf8b)
Solutions
- Keep accumulated quantities below i128 range: validate raw <= i128::MAX * FIXED_SCALAR_RAW before further accumulation.
- Cap quantities at domain level (max order/position sizes) so raw values stay far below the boundary.
- Use a wider accumulation type (big-int) for aggregation and only construct Quantity after validation.
- Report this as a bug if hit with ordinary values; in default u64 builds it is unreachable.
Example fix
// before
let huge = Quantity::from_raw(u128::MAX / 2, precision);
println!("{}", huge); // panics inside raw_as_decimal
// after
let qty = Quantity::from_raw(1_500_000_u64, precision); // comfortably representable
println!("{}", qty); Defensive patterns
Strategy: validation
Validate before calling
// Rust (high-precision u128 builds)
fn whole_fits_i128(raw: u128, fixed_scalar_raw: u128) -> bool {
raw / fixed_scalar_raw <= i128::MAX as u128
} Prevention
- Cap quantities at domain level so raw values stay far below i128 range.
- In high-precision builds, validate u128 raws before formatting/displaying quantities.
- Avoid sentinel max values (u128::MAX) leaking in from imports or fixtures.
- Report occurrences with ordinary values as bugs; unreachable in default u64 builds.
When it happens
Trigger: Calling internal raw_as_decimal (used by Quantity::as_decimal and Display) with a raw u128 quantity whose whole part exceeds i128::MAX; triggered indirectly by any Display/format/as_decimal call on such a Quantity.
Common situations: High-precision builds with astronomically large quantities produced by unbounded multiplication; aggregating quantities until the raw value passes i128 range; data-import bugs writing sentinel max values.
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
- Fractional raw quantity must fit in Decimal
- Overflow in Quantity::from_mantissa_exponent
- Raw value exceeds QuantityRaw range in Quantity::from_mantis
- Overflow occurred when adding `Quantity`
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/e49e1b11797f3d4e.
Report an issue: GitHub.