nautechsystems/nautilus_trader · error
Overflow occurred when adding `Price`
Error message
Overflow occurred when adding `Price`
What it means
Price implements Add by checked_add on the raw fixed-point integers; if the sum exceeds the raw integer range, checked_add returns None and this expect panics. The library refuses to wrap prices silently because a wrapped price would be silently wrong in trading logic.
Source
Thrown at crates/model/src/types/price.rs:683
Self {
raw: -self.raw,
precision: self.precision,
}
}
}
impl Add for Price {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
assert!(
raw_scales_match(self.precision, rhs.precision),
"Cannot add `Price` values with mismatched decimal scales"
);
Self {
raw: self
.raw
.checked_add(rhs.raw)
.expect("Overflow occurred when adding `Price`"),
precision: self.precision.max(rhs.precision),
}
}
}
impl Sub for Price {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
assert!(
raw_scales_match(self.precision, rhs.precision),
"Cannot subtract `Price` values with mismatched decimal scales"
);
Self {
raw: self
.raw
.checked_sub(rhs.raw)
.expect("Underflow occurred when subtracting `Price`"),
precision: self.precision.max(rhs.precision),View on GitHub (pinned to 18893faf8b)
Solutions
- Check before adding (e.g. compare raw values against PRICE_RAW_MAX - lhs.raw) or use a checked/widened accumulation type such as Decimal or i128 for intermediate sums.
- Reduce operand magnitudes: the sum of the intended values should be representable; if not, the operation is semantically invalid for Price.
- Track running sums with rust_decimal::Decimal and construct a Price only at the end after range validation.
- Enable the high-precision build so PriceRaw is wider if large sums are legitimate.
Example fix
// before let total: Price = prices.iter().copied().fold(Price::zero(precision), |a, b| a + b); // panics on overflow // after let total_dec = prices.iter().fold(Decimal::ZERO, |a, p| a + p.as_decimal()); let total = Price::new(total_dec, precision); // validate range at construction
Defensive patterns
Strategy: fallback
Validate before calling
// Rust
fn checked_price_add(a: Price, b: Price) -> Option<Price> {
(a.precision == b.precision)
.then(|| a.raw.checked_add(b.raw))
.flatten()
.map(|raw| Price { raw, precision: a.precision })
} Try / catch
// Prices are non-panicking only via checked math; accumulate in Decimal: let sum: Decimal = prices.iter().fold(Decimal::ZERO, |a, p| a + p.as_decimal()); assert!(sum <= PRICE_MAX_DECIMAL, "price accumulation exceeded representable range");
Prevention
- Never accumulate prices in a fold over Price; use Decimal for running totals.
- Check headroom before large aggregations.
- Remember Price addition is a domain operation with bounded range, not a general numeric sum.
- Test aggregation code paths with max-precision max-value prices.
When it happens
Trigger: Using the + operator (impl Add for Price) on two Price values with equal precision whose raw sum exceeds PRICE_RAW_MAX; also via iterated addition accumulating large prices.
Common situations: Aggregating notional/price values in a loop (sums of thousands of large prices); porting code that used f64 and never overflowed; configuring instruments with very high precision leaving little headroom in the raw integer.
Related errors
- Overflow in Price::from_mantissa_exponent
- Raw value exceeds PriceRaw range in Price::from_mantissa_exp
- Overflow occurred when adding `Quantity`
- Liquidity addition overflow: x={current}, y={y}, delta={delt
- precision exceeded i8 range
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ab97be71ce4acb3b.
Report an issue: GitHub.