{"record":{"id":"5e075a57789aa03e","repo":"nautechsystems/nautilus_trader","slug":"bitmex-only-supports-l2-mbp-order-book-deltas","errorCode":null,"errorMessage":"BitMEX only supports L2_MBP order book deltas","messagePattern":"BitMEX only supports L2_MBP order book deltas","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/bitmex/src/data.rs","lineNumber":784,"sourceCode":"\n        log::warn!(\"Instrument {instrument_id} not found in BitMEX cache\");\n\n        let ws = self.ws_client()?.clone();\n        self.spawn_ws(\n            async move {\n                ws.subscribe_instrument(instrument_id)\n                    .await\n                    .map_err(|e| anyhow::anyhow!(e))\n            },\n            \"BitMEX instrument subscription\",\n        );\n\n        Ok(())\n    }\n\n    fn subscribe_book_deltas(&mut self, cmd: SubscribeBookDeltas) -> anyhow::Result<()> {\n        if cmd.book_type != BookType::L2_MBP {\n            anyhow::bail!(\"BitMEX only supports L2_MBP order book deltas\");\n        }\n\n        let instrument_id = cmd.instrument_id;\n        let depth = cmd.depth.map_or(0, |d| d.get());\n        let channel = if depth > 0 && depth <= 25 {\n            if depth != 25 {\n                log::debug!(\n                    \"BitMEX only supports depth 25 for L2 deltas, using L2_25 for requested depth {depth}\"\n                );\n            }\n            BitmexBookChannel::OrderBookL2_25\n        } else {\n            BitmexBookChannel::OrderBookL2\n        };\n\n        let ws = self.ws_client()?.clone();\n        let book_channels = Arc::clone(&self.book_channels);\n","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bitmex/src/data.rs#L766-L802","documentation":"subscribe_book_deltas capability check: BitMEX's WebSocket book feed only provides L2 market-by-price data, so a SubscribeBookDeltas command with any other BookType (e.g. L1_MBP or L3_MBO) is rejected at subscription time.","triggerScenarios":"Calling subscribe_book_deltas with cmd.book_type != BookType::L2_MBP, e.g. requesting L3_MBO order book data from the BitMEX data client.","commonSituations":"Configs that request L3 data because another venue adapter supports it, or depth/book-type defaults carried over from a different venue's data client configuration.","solutions":["Set book_type to L2_MBP in the subscription request / data client config for BitMEX","Request a supported depth (<=25 selects the orderBookL2_25 channel, otherwise orderBook10)","Route L3_MBO subscriptions to a venue that supports them instead of BitMEX"],"exampleFix":"// before\nclient.subscribe_book_deltas(SubscribeBookDeltas { book_type: BookType::L3_MBO, ... })\n// after\nclient.subscribe_book_deltas(SubscribeBookDeltas { book_type: BookType::L2_MBP, ... })","handlingStrategy":"validation","validationCode":"if book_type != BookType::L2_MBP {\n    return Err(\"BitMEX data subscriptions require BookType::L2_MBP\");\n}","typeGuard":"fn is_l2_mbp(bt: BookType) -> bool { matches!(bt, BookType::L2_MBP) }","tryCatchPattern":null,"preventionTips":["Set book_type=L2_MBP in BitMEX data client configs","Keep depth within supported channels (<=25 or orderBook10)","Centralize per-venue data capability checks"],"tags":["bitmex","order-book","subscription"],"backgroundTag":"unsupported-config-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}