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

  1. 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.
  2. Reduce operand magnitudes: the sum of the intended values should be representable; if not, the operation is semantically invalid for Price.
  3. Track running sums with rust_decimal::Decimal and construct a Price only at the end after range validation.
  4. 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

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


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