{"record":{"id":"0c714b6775e333db","repo":"nautechsystems/nautilus_trader","slug":"invalid-ask-quantity-for-orderbook-filtered-view","errorCode":null,"errorMessage":"Invalid ask quantity for OrderBook::filtered_view","messagePattern":"Invalid ask quantity for OrderBook::filtered_view","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/model/src/orderbook/book.rs","lineNumber":841,"sourceCode":"                Price::from_decimal(price).expect(\"Invalid bid price for OrderBook::filtered_view\"),\n                Quantity::from_decimal(quantity)\n                    .expect(\"Invalid bid quantity for OrderBook::filtered_view\"),\n                order_id,\n            );\n            order_id += 1;\n            filtered_book.add(order, 0, sequence, ts_event);\n        }\n\n        for (price, quantity) in asks_map {\n            if quantity <= Decimal::ZERO {\n                continue;\n            }\n\n            let order = BookOrder::new(\n                OrderSide::Sell,\n                Price::from_decimal(price).expect(\"Invalid ask price for OrderBook::filtered_view\"),\n                Quantity::from_decimal(quantity)\n                    .expect(\"Invalid ask quantity for OrderBook::filtered_view\"),\n                order_id,\n            );\n            order_id += 1;\n            filtered_book.add(order, 0, sequence, ts_event);\n        }\n\n        Ok(filtered_book)\n    }\n\n    /// Groups bid quantities into price buckets, truncating to a maximum depth, excluding own orders.\n    ///\n    /// With `own_book`, subtracts own order sizes, filtered by `status` if provided.\n    /// When `now` is provided, only subtracts orders whose acceptance time plus\n    /// `accepted_buffer_ns` is at or before `now`. When `now` is `None`, acceptance-time\n    /// filtering is disabled.\n    ///\n    /// # Panics\n    ///","sourceCodeStart":823,"sourceCodeEnd":859,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/model/src/orderbook/book.rs#L823-L859","documentation":"In OrderBook::filtered_view, each synthetic ask quantity is converted with Quantity::from_decimal(...).expect(...) and panics with this message on failure. from_decimal returns None for negative, non-finite, or precision/range-violating decimals; the surrounding code already skips quantity <= 0, so this panic indicates a non-finite quantity or a precision violation.","triggerScenarios":"Calling filtered_view / py_filtered_view with an asks map whose quantity is NaN, infinite, or exceeds the supported decimal precision (unrounded float artifacts, oversized values).","commonSituations":"Raw floating-point computations inserted directly as quantities; parsing external data with more decimal places than allowed; size precision changed on the instrument without renormalizing the map.","solutions":["Round ask quantities to the instrument size precision and assert finiteness before calling filtered_view.","Filter out non-finite entries when constructing the asks map.","Use the project's Quantity/from_raw fixed-point path instead of ad-hoc decimal conversion.","Sanitize external inputs at parse time.","Mirror the same validation used for the bids side to keep behavior consistent."],"exampleFix":"// before\nasks.insert(price, Quantity::from_decimal(unrounded_qty_dec));\n// after\nlet q = unrounded_qty_dec.round_dp(instrument.size_precision as u32);\ndebug_assert!(q.is_finite() && q.is_sign_positive());\nasks.insert(price, Quantity::from_decimal(q));","handlingStrategy":"validation","validationCode":"fn valid_ask_qty(q: &Quantity) -> bool {\n    let d = q.as_decimal();\n    d.is_finite() && d.is_sign_positive()\n}\nassert!(ask_map.iter().all(|(_, q)| valid_ask_qty(q)));","typeGuard":"fn is_valid_quantity(q: &Quantity) -> bool {\n    q.as_decimal().is_finite()\n}","tryCatchPattern":"// Validate before the call; panics are not recoverable in Rust. Python:\ntry:\n    view = book.filtered_view(bids, asks, None)\nexcept BaseException as e:\n    log.warning(\"filtered_view failed: %s\", e)","preventionTips":["Round ask quantities to size precision before insertion.","Drop non-finite quantities when building maps.","Use the fixed-point Quantity APIs instead of ad-hoc decimals."],"tags":["rust","orderbook","panic","invalid-argument-value","decimal"],"backgroundTag":"invalid-argument-value","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"}