{"record":{"id":"395d4614ed59e66d","repo":"nautechsystems/nautilus_trader","slug":"overflow-occurred-when-adding-quantity","errorCode":null,"errorMessage":"Overflow occurred when adding `Quantity`","messagePattern":"Overflow occurred when adding `Quantity`","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/types/quantity.rs","lineNumber":702,"sourceCode":"    type Target = QuantityRaw;\n\n    fn deref(&self) -> &Self::Target {\n        &self.raw\n    }\n}\n\nimpl Add for Quantity {\n    type Output = Self;\n    fn add(self, rhs: Self) -> Self::Output {\n        assert!(\n            raw_scales_match(self.precision, rhs.precision),\n            \"Cannot add `Quantity` values with mismatched decimal scales\"\n        );\n        Self {\n            raw: self\n                .raw\n                .checked_add(rhs.raw)\n                .expect(\"Overflow occurred when adding `Quantity`\"),\n            precision: self.precision.max(rhs.precision),\n        }\n    }\n}\n\nimpl Sum for Quantity {\n    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {\n        iter.reduce(|acc, x| acc + x)\n            .unwrap_or_else(|| Self::zero(0))\n    }\n}\n\nimpl<'a> Sum<&'a Self> for Quantity {\n    fn sum<I: Iterator<Item = &'a Self>>(iter: I) -> Self {\n        iter.copied().sum()\n    }\n}\n","sourceCodeStart":684,"sourceCodeEnd":720,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/types/quantity.rs#L684-L720","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nlet filled: Quantity = fills.iter().map(|f| f.qty).sum(); // panics on very large totals\n// after\nlet total = fills.iter().fold(Decimal::ZERO, |a, f| a + f.qty.as_decimal());\nlet filled = Quantity::new(total, precision); // validates range","handlingStrategy":"fallback","validationCode":"// Rust\nfn checked_quantity_add(a: Quantity, b: Quantity) -> Option<Quantity> {\n    (a.precision == b.precision)\n        .then(|| a.raw.checked_add(b.raw))\n        .flatten()\n        .map(|raw| Quantity { raw, precision: a.precision })\n}","typeGuard":null,"tryCatchPattern":"// Accumulate in Decimal, then build once:\nlet total = fills.iter().fold(Decimal::ZERO, |a, f| a + f.qty.as_decimal());\nassert!(total <= MAX_QUANTITY_DECIMAL);\nlet filled = Quantity::new(total, precision);","preventionTips":["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."],"tags":["rust","arithmetic-overflow","panic","quantity","addition"],"backgroundTag":"arithmetic-overflow","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}