{"record":{"id":"ad7a9877823af233","repo":"nautechsystems/nautilus_trader","slug":"requestjoin-must-be-handled-by-handle-request-join","errorCode":null,"errorMessage":"RequestJoin must be handled by handle_request_join","messagePattern":"RequestJoin must be handled by handle_request_join","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/data/src/engine/mod.rs","lineNumber":1384,"sourceCode":"        };\n        let resolved_client_id = client.client_id();\n\n        match req {\n            RequestCommand::Data(req) => client.request_data(req),\n            RequestCommand::Instrument(req) => client.request_instrument(req),\n            RequestCommand::Instruments(req) => client.request_instruments(req),\n            RequestCommand::BookSnapshot(req) => client.request_book_snapshot(req),\n            RequestCommand::BookDeltas(req) => client.request_book_deltas(req),\n            RequestCommand::BookDepth(req) => client.request_book_depth(req),\n            RequestCommand::Quotes(req) => client.request_quotes(req),\n            RequestCommand::Trades(req) => client.request_trades(req),\n            RequestCommand::FundingRates(req) => client.request_funding_rates(req),\n            RequestCommand::OptionChainReferencePrice(req) => {\n                client.request_option_chain_reference_price(req)\n            }\n            RequestCommand::Bars(req) => client.request_bars(req),\n            RequestCommand::Join(_) => {\n                anyhow::bail!(\"RequestJoin must be handled by handle_request_join\")\n            }\n        }?;\n\n        Ok(resolved_client_id)\n    }\n\n    fn execute_continuous_future_request(&mut self, req: RequestCommand) -> anyhow::Result<()> {\n        let RequestCommand::Bars(parent) = req else {\n            anyhow::bail!(\"Continuous future requests require `RequestBars`\");\n        };\n        let request_id = parent.request_id;\n        let Some(continuous_request) = continuous_future_request_from_bars(&parent)? else {\n            return Ok(());\n        };\n\n        self.ensure_continuous_future_target_instrument(&continuous_request);\n        self.prepare_request_bar_aggregators_from_state(\n            request_id,","sourceCodeStart":1366,"sourceCodeEnd":1402,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/data/src/engine/mod.rs#L1366-L1402","documentation":"RequestCommand::Join requests are not processed by the generic request dispatch path; they have a dedicated handle_request_join method. Reaching the generic match arm with a Join request indicates an internal routing invariant was violated, so the engine bails.","triggerScenarios":"Calling DataEngine.request (execute_request) with a RequestCommand::Join payload instead of calling handle_request_join; a code path that funnels all RequestCommand variants through the generic dispatcher.","commonSituations":"Custom integration or subclass code that wraps engine.request for every command type; refactors that removed the special-case routing for join requests; passing a join request into a generic batch-request helper.","solutions":["Route RequestCommand::Join through DataEngine.handle_request_join instead of request/execute_request","In generic dispatch code, match RequestCommand::Join first and delegate to handle_request_join","Check the library version's API: join requests have a dedicated entry point, not the generic one","If this arises without custom routing code, report it as an internal invariant bug"],"exampleFix":"// before\nengine.request(RequestCommand::Join(join_req));\n// after\nengine.handle_request_join(join_req);","handlingStrategy":"validation","validationCode":"if let RequestCommand::Join(join) = &cmd {\n    engine.handle_request_join(join.clone());\n    return Ok(());\n}\nengine.request(cmd);","typeGuard":"fn is_join(cmd: &RequestCommand) -> Option<&RequestJoin> {\n    match cmd { RequestCommand::Join(j) => Some(j), _ => None }\n}","tryCatchPattern":"match engine.request(cmd) {\n    Err(e) if e.to_string().contains(\"handle_request_join\") => {\n        // reroute via handle_request_join\n    }\n    other => other?,\n}","preventionTips":["Never route RequestCommand::Join through the generic request dispatcher","In generic wrappers, special-case Join before dispatching","Keep dispatch match arms aligned with the engine's documented entry points"],"tags":["rust","data-engine","internal-invariant","request-routing"],"backgroundTag":"internal-invariant-violation","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"}