nautechsystems/nautilus_trader · error
Overflow occurred when adding `Quantity`
Error message
Overflow occurred when adding `Quantity`
What it means
Quantity implements Add via checked_add on raw fixed-point values; a None result (sum above QUANTITY_RAW_MAX) makes the expect panic. Silent wrapping of a quantity would corrupt order/position accounting, so the library aborts loudly instead.
Source
Thrown at crates/model/src/types/quantity.rs:702
type Target = QuantityRaw;
fn deref(&self) -> &Self::Target {
&self.raw
}
}
impl Add for Quantity {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
assert!(
raw_scales_match(self.precision, rhs.precision),
"Cannot add `Quantity` values with mismatched decimal scales"
);
Self {
raw: self
.raw
.checked_add(rhs.raw)
.expect("Overflow occurred when adding `Quantity`"),
precision: self.precision.max(rhs.precision),
}
}
}
impl Sum for Quantity {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.reduce(|acc, x| acc + x)
.unwrap_or_else(|| Self::zero(0))
}
}
impl<'a> Sum<&'a Self> for Quantity {
fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {
iter.copied().sum()
}
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Accumulate in Decimal or u128 and construct/validate a Quantity at the end instead of repeatedly adding Quantity.
- Check remaining headroom (QUANTITY_RAW_MAX - lhs.raw) >= rhs.raw before adding.
- Enforce domain caps (max order size, max position) so accumulated raw values stay far below the bound.
- Verify both quantities use consistent units/precision from each venue before summing.
Example fix
// before let filled: Quantity = fills.iter().map(|f| f.qty).sum(); // panics on very large totals // after let total = fills.iter().fold(Decimal::ZERO, |a, f| a + f.qty.as_decimal()); let filled = Quantity::new(total, precision); // validates range
Defensive patterns
Strategy: fallback
Validate before calling
// Rust
fn checked_quantity_add(a: Quantity, b: Quantity) -> Option<Quantity> {
(a.precision == b.precision)
.then(|| a.raw.checked_add(b.raw))
.flatten()
.map(|raw| Quantity { raw, precision: a.precision })
} Try / catch
// Accumulate in Decimal, then build once: let total = fills.iter().fold(Decimal::ZERO, |a, f| a + f.qty.as_decimal()); assert!(total <= MAX_QUANTITY_DECIMAL); let filled = Quantity::new(total, precision);
Prevention
- Accumulate fills in Decimal or u128; construct Quantity only after validation.
- Enforce max order/position size caps so sums stay far below QUANTITY_RAW_MAX.
- Confirm unit consistency across venues before summing.
- Exercise aggregation paths with near-max quantities in tests.
When it happens
Trigger: Using + on two Quantity values with matching precision whose raw sum exceeds QUANTITY_RAW_MAX; also via impl Sum / fold over collections of large quantities.
Common situations: Accumulating filled quantities across many fills; summing position sizes in a portfolio loop; unit mismatches where one venue reports in minimal units and inflates sums.
Related errors
- Overflow occurred when adding `Price`
- Whole raw quantity must fit in Decimal
- Overflow in Quantity::from_mantissa_exponent
- Raw value exceeds QuantityRaw range in Quantity::from_mantis
- Liquidity addition overflow: x={current}, y={y}, delta={delt
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/395d4614ed59e66d.
Report an issue: GitHub.