{"record":{"id":"6c793a1cf980a480","repo":"nautechsystems/nautilus_trader","slug":"derive-only-supports-l2-mbp-order-book-deltas","errorCode":null,"errorMessage":"Derive only supports L2_MBP order book deltas","messagePattern":"Derive only supports L2_MBP order book deltas","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/derive/src/data.rs","lineNumber":803,"sourceCode":"\n        self.is_connected.store(true, Ordering::Release);\n        setup_guard.disarm();\n        log::info!(\n            \"Connected Derive data client ({:?})\",\n            self.config.environment\n        );\n        Ok(())\n    }\n\n    async fn disconnect(&mut self) -> anyhow::Result<()> {\n        self.teardown_partial_connect().await?;\n        log::info!(\"Disconnected Derive data client\");\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!(\"Derive only supports L2_MBP order book deltas\");\n        }\n\n        let instrument_id = cmd.instrument_id;\n        let owner = ChannelOwner::BookDeltas(instrument_id);\n        let lifecycle = self.subscription_lifecycle();\n        if lifecycle.is_active(owner) {\n            return Ok(());\n        }\n\n        let instrument_name = format_venue_symbol(&instrument_id)?.to_string();\n        let group = orderbook_group(&cmd.params)?;\n        let depth = orderbook_depth(cmd.depth.map(|d| d.get()), &cmd.params)?;\n        let channel = orderbook_channel(&instrument_name, &group, &depth);\n        let request = ChannelRequest::from_channel(&channel)?;\n        let needs_load = self.prepare_subscribe(instrument_id)?;\n        let Some(generation) = lifecycle.activate(owner, Some(&channel)) else {\n            return Ok(());\n        };","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/derive/src/data.rs#L785-L821","documentation":"Raised by `subscribe_book_deltas` when the requested order book type is not `BookType::L2_MBP`. Derive's WebSocket order book feed only provides level-2 market-by-price data, so other book types (e.g. L3_MBO) are rejected up front.","triggerScenarios":"Issuing a SubscribeBookDeltas command with `book_type` set to anything other than L2_MBP (e.g. L1_MBP or L3_MBO) against the Derive data client.","commonSituations":"Reusing subscription code written for venues supporting L3/MBO data; strategy configs specifying a deeper or aggregated book type; copy-pasted subscribe calls across adapters.","solutions":["Change the subscription command to use BookType::L2_MBP.","If L3/MBO granularity is required, use a different adapter/venue that supports it.","Validate the book_type in your strategy config before subscribing."],"exampleFix":"// before\nlet cmd = SubscribeBookDeltas { book_type: BookType::L3_MBO, ..cmd };\n// after\nlet cmd = SubscribeBookDeltas { book_type: BookType::L2_MBP, ..cmd };","handlingStrategy":"validation","validationCode":"assert!(matches!(cmd.book_type, BookType::L2_MBP), \"Derive book deltas require L2_MBP\");","typeGuard":null,"tryCatchPattern":"if cmd.book_type != BookType::L2_MBP {\n    log::warn!(\"coercing book_type to L2_MBP for Derive\");\n    cmd.book_type = BookType::L2_MBP;\n}","preventionTips":["Constrain book subscriptions to L2_MBP for Derive in strategy configs.","Centralize venue capability checks in one place before subscribing.","Fall back to trades/ticker feeds when L3 data is needed but unsupported."],"tags":["order-book","subscription","unsupported-value","derive"],"backgroundTag":"unsupported-operation","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"}