{"record":{"id":"b562ed2294b21c53","repo":"nautechsystems/nautilus_trader","slug":"invalid-binance-futures-order-book-depth-valid-va","errorCode":null,"errorMessage":"invalid Binance Futures order-book depth; valid values are {:?}","messagePattern":"invalid Binance Futures order-book depth; valid values are (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/http/client.rs","lineNumber":3059,"sourceCode":"            .request_binance_bars(bar_type, start, end, limit)\n            .await?\n            .into_iter()\n            .map(|bar| bar.bar())\n            .collect())\n    }\n\n    /// Requests an explicit L2 order-book snapshot.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error for an invalid depth, missing instrument, request failure, or invalid level.\n    pub async fn request_book_snapshot(\n        &self,\n        instrument_id: InstrumentId,\n        depth: Option<u32>,\n    ) -> anyhow::Result<OrderBook> {\n        if depth.is_some_and(|value| !crate::common::consts::BINANCE_BOOK_DEPTHS.contains(&value)) {\n            anyhow::bail!(\n                \"invalid Binance Futures order-book depth; valid values are {:?}\",\n                crate::common::consts::BINANCE_BOOK_DEPTHS\n            );\n        }\n        let (symbol, price_precision, size_precision) =\n            self.cached_precisions_by_id(instrument_id)?;\n        let params = BinanceDepthParams {\n            symbol,\n            limit: depth,\n        };\n        let snapshot = self.inner.depth(&params).await?;\n        let ts_event = self.clock.get_time_ns();\n        let sequence = u64::try_from(snapshot.last_update_id)\n            .map_err(|_| anyhow::anyhow!(\"invalid negative order-book update ID\"))?;\n        let mut book = OrderBook::new(instrument_id, BookType::L2_MBP);\n        for (index, level) in snapshot.bids.iter().enumerate() {\n            let order = BookOrder::new(\n                OrderSide::Buy,","sourceCodeStart":3041,"sourceCodeEnd":3077,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/futures/http/client.rs#L3041-L3077","documentation":"Thrown by BinanceFuturesHttpClient::request_book_snapshot when an explicit depth is supplied that is not one of Binance's allowed limits [5, 10, 20, 50, 100, 500, 1000] (crate::common::consts::BINANCE_BOOK_DEPTHS). The venue's depth endpoint only accepts those discrete limits, so the client validates before the request and the message enumerates the full valid set. Passing depth=None is fine — the venue picks a default.","triggerScenarios":"Calling request_book_snapshot(instrument_id, Some(d)) with d like 25, 200, or 10000; UI knobs or config files exposing an unconstrained depth integer; copying depth values from another venue's adapter with different allowed sets.","commonSituations":"Config-driven order-book depth ('depth = 50' works, 'depth = 25' fails); porting spot-vs-futures assumptions where valid sets differ; truncating a user-requested N-level view directly into the venue depth parameter instead of fetching a valid superset and trimming.","solutions":["Pass None for the default, or clamp the requested depth up to the nearest allowed value in [5,10,20,50,100,500,1000]","Validate depth against BINANCE_BOOK_DEPTHS at config load time with a clear error","If you need exactly N levels, request the next larger valid depth and truncate the returned book client-side"],"exampleFix":"// before\nlet book = client.request_book_snapshot(instrument_id, Some(25)).await?;\n\n// after\nconst VALID: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];\nlet depth = Some(25).map(|d| VALID.iter().copied().find(|&v| v >= d).unwrap_or(1000));\nlet book = client.request_book_snapshot(instrument_id, depth).await?;","handlingStrategy":"validation","validationCode":"const VALID: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];\nlet depth = requested_depth.map(|d| {\n    VALID.iter().copied().find(|&v| v >= d).unwrap_or(1000)\n});\nassert!(depth.is_none_or(|d| VALID.contains(&d)));","typeGuard":"fn is_valid_binance_depth(depth: u32) -> bool {\n    [5, 10, 20, 50, 100, 500, 1000].contains(&depth)\n}","tryCatchPattern":"On this bail, clamp the depth to the nearest allowed value (round up) and retry; None also works if the exact level count does not matter.","preventionTips":["Validate depth at config load against the allowed set","Clamp arbitrary UI depth values up to a valid limit","Trim returned books client-side when an exact level count is needed"],"tags":["binance","futures","order-book","depth","validation","rust","nautilustrader"],"backgroundTag":"invalid-request-parameter","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}