{"record":{"id":"3dd5d8976dda2259","repo":"nautechsystems/nautilus_trader","slug":"invalid-binance-futures-order-book-depth-depth","errorCode":null,"errorMessage":"invalid Binance Futures order-book depth {depth}; valid values are {BINANCE_BOOK_DEPTHS:?}","messagePattern":"invalid Binance Futures order-book depth (.+?); valid values are (.+?)","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/binance/src/futures/data.rs","lineNumber":3044,"sourceCode":"                        end_nanos,\n                        clock.get_time_ns(),\n                        params,\n                    ));\n\n                    if let Err(e) = sender.send(DataEvent::Response(response)) {\n                        log::error!(\"Failed to send bars response: {e}\");\n                    }\n                }\n                Err(e) => log::error!(\"Bar request failed: {e:?}\"),\n            }\n        });\n\n        Ok(())\n    }\n\n    fn request_book_snapshot(&self, request: RequestBookSnapshot) -> anyhow::Result<()> {\n        let depth = request.depth.map_or(1000, |value| value.get() as u32);\n        anyhow::ensure!(\n            BINANCE_BOOK_DEPTHS.contains(&depth),\n            \"invalid Binance Futures order-book depth {depth}; valid values are {BINANCE_BOOK_DEPTHS:?}\"\n        );\n        let http = self.http_client.clone();\n        let sender = self.data_sender.clone();\n        let instrument_id = request.instrument_id;\n        let request_id = request.request_id;\n        let client_id = request.client_id.unwrap_or(self.client_id);\n        let params = request.params;\n        let clock = self.clock;\n\n        get_runtime().spawn(async move {\n            match http.request_book_snapshot(instrument_id, Some(depth)).await {\n                Ok(book) => {\n                    let response = DataResponse::Book(BookResponse::new(\n                        request_id,\n                        client_id,\n                        instrument_id,","sourceCodeStart":3026,"sourceCodeEnd":3062,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/binance/src/futures/data.rs#L3026-L3062","documentation":"Thrown by request_book_snapshot on the Binance Futures data client when the requested order-book depth is not one of the exchange-supported levels. Binance futures /fapi/v1/depth and /dapi/v1/depth accept only the depths mirrored in BINANCE_BOOK_DEPTHS = [5, 10, 20, 50, 100, 500, 1000] (crates/adapters/binance/src/common/consts.rs:338). When request.depth is None the client defaults to 1000, which is always accepted.","triggerScenarios":"Sending a RequestBookSnapshot whose depth field holds an unsupported value such as 25, 200, or 2000 — e.g. depth copied from another venue's config or computed dynamically from user settings.","commonSituations":"Reusing a Bybit/OKX depth setting (those venues allow 25/200) on the Binance futures adapter; passing a raw user-supplied 'limit' straight into the request without whitelisting.","solutions":["Set depth to one of 5, 10, 20, 50, 100, 500, or 1000","Omit depth (pass None) to use the default of 1000","Validate any user-configured depth against the allowed list before submitting the snapshot request"],"exampleFix":"// before\nlet request = RequestBookSnapshot::new(instrument_id, client_id, request_id, Some(200.non_zero()?));\n\n// after\nlet request = RequestBookSnapshot::new(instrument_id, client_id, request_id, Some(500.non_zero()?));","handlingStrategy":"validation","validationCode":"const BINANCE_BOOK_DEPTHS: [u32; 7] = [5, 10, 20, 50, 100, 500, 1000];\n\nlet depth = requested_depth.unwrap_or(1000);\nassert!(BINANCE_BOOK_DEPTHS.contains(&depth), \"depth must be one of {BINANCE_BOOK_DEPTHS:?}\");\n// then send RequestBookSnapshot","typeGuard":"fn is_valid_binance_depth(depth: u32) -> bool {\n    [5, 10, 20, 50, 100, 500, 1000].contains(&depth)\n}","tryCatchPattern":null,"preventionTips":["Whitelist user-supplied depth values against the venue's documented levels at config load","Default to None (1000) rather than inventing a depth","Remember spot and futures depth lists can differ — validate per adapter"],"tags":["binance-futures","orderbook","depth","snapshot","rust"],"backgroundTag":"invalid-orderbook-depth","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}