{"record":{"id":"8b7bd53a0a2b21fe","repo":"nautechsystems/nautilus_trader","slug":"reduce-only-quantity-overflow-for-order-client-or","errorCode":null,"errorMessage":"Reduce-only quantity overflow for order {client_order_id}","messagePattern":"Reduce-only quantity overflow for order (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/execution/src/matching_engine/mod.rs","lineNumber":5433,"sourceCode":"                continue;\n            }\n\n            // Re-read after dispatch: synchronous handlers can apply this fill immediately,\n            // while pending fills account for a cache that has not acknowledged it yet.\n            let position = self.cache.borrow().position(&position.id).map_or_else(\n                || position.clone_without_events(),\n                |position| position.clone_without_events(),\n            );\n\n            let remaining = self.position_quantity_remaining(&order, &position)?;\n            if remaining.is_zero() {\n                self.cancel_reduce_only_order(&order, filled_order.client_order_id())?;\n                continue;\n            }\n\n            let leaves = self.parent_capped_leaves(&order, remaining);\n            let target = order.filled_qty().checked_add(leaves).ok_or_else(|| {\n                anyhow::anyhow!(\"Reduce-only quantity overflow for order {client_order_id}\")\n            })?;\n\n            if order.quantity() != target {\n                // Quantity maintenance must not re-enter matching while a fill loop is active\n                self.generate_order_updated(\n                    &order,\n                    target,\n                    order.price(),\n                    order.trigger_price(),\n                    None,\n                );\n\n                if target == order.filled_qty() {\n                    self.cancel_reduce_only_order(&order, filled_order.client_order_id())?;\n                } else if self.config.support_contingent_orders\n                    && order.contingency_type() == Some(ContingencyType::Ouo)\n                {\n                    self.sync_ouo_leaves(&order, leaves, filled_order.client_order_id())?;","sourceCodeStart":5415,"sourceCodeEnd":5451,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/execution/src/matching_engine/mod.rs#L5415-L5451","documentation":"For reduce-only orders, the engine recomputes the order's leaves quantity capped by the remaining position size and then computes target = filled_qty + leaves using checked arithmetic. If that addition overflows the Decimal capacity, the resulting order quantity would be invalid, so the engine raises this error during quantity maintenance of the reduce-only order.","triggerScenarios":"Processing a reduce-only order where parent_capped_leaves returns a value that, added to the order's filled_qty, exceeds Decimal capacity — typically from extreme quantity magnitudes, very high precision, or inconsistent quantity scale between filled_qty and the computed leaves.","commonSituations":"Backtests with enormous notional quantities on high-precision instruments; an instrument whose configured size precision makes quantity values near the Decimal max; custom adapters feeding inconsistent quantity precisions into fills.","solutions":["Reduce the order/instrument quantity magnitude or precision so filled_qty + capped leaves fits in the Decimal max.","Ensure filled_qty and the capped leaves share the same precision/scale before addition (normalize quantity precisions).","Audit the reduce-only sizing logic: capped leaves should not exceed the position's remaining absolute quantity.","Reproduce with logging of filled_qty and leaves values just before the checked_add to identify the scale explosion."],"exampleFix":"// before: mixed precisions can push target out of range\nlet leaves = self.parent_capped_leaves(&order, remaining);\nlet target = order.filled_qty().checked_add(leaves).ok_or(...)?;\n// after: normalize precision before computing target\nlet leaves = leaves.normalize(order.filled_qty().precision);\nlet target = order.filled_qty().checked_add(leaves).ok_or(...)?;","handlingStrategy":"validation","validationCode":"// bound reduce-only sizing before the order reaches the engine\nlet capped = leaves.min(position.quantity.abs());\nlet target = order.filled_qty().checked_add(capped);\nassert!(target.is_some(), \"reduce-only target quantity would overflow\");","typeGuard":null,"tryCatchPattern":"match engine.iteration(&mut command_queue) {\n    Err(e) if e.to_string().starts_with(\"Reduce-only quantity overflow\") => {\n        log::error!(\"{e}; cancelling reduce-only order\");\n        // cancel the offending order and fix its quantity scale\n    }\n    other => other,\n}","preventionTips":["Normalize quantity precision of fills and order quantities on a single instrument.","Cap reduce-only order quantities to the position's absolute quantity.","Avoid extreme quantity magnitudes in backtest configurations."],"tags":["matching-engine","reduce-only","decimal-overflow","checked-arithmetic"],"backgroundTag":"value-out-of-range","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"}