{"record":{"id":"20b61ca63f2b3217","repo":"nautechsystems/nautilus_trader","slug":"cannot-add-strategy-while-node-is-running-add-str","errorCode":null,"errorMessage":"Cannot add strategy while node is running, add strategies before running the node","messagePattern":"Cannot add strategy while node is running, add strategies before running the node","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/node/mod.rs","lineNumber":2699,"sourceCode":"    /// Strategies are registered in both the component registry (for lifecycle management)\n    /// and the actor registry (for data callbacks via msgbus).\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - The node is currently running.\n    /// - A strategy with the same ID is already registered.\n    /// - The configured external order instrument IDs repeat an instrument or the cache already\n    ///   contains a requested claim.\n    /// - The strategy configures one or more external order instrument IDs and the cache is already\n    ///   borrowed.\n    /// - The strategy configures an OMS type override and the execution engine is already borrowed.\n    pub fn add_strategy<T>(&mut self, mut strategy: T) -> anyhow::Result<()>\n    where\n        T: Strategy + StrategyNative + DataActorNative + Component + Debug + 'static,\n    {\n        if self.state() != NodeState::Idle {\n            anyhow::bail!(\n                \"Cannot add strategy while node is running, add strategies before running the node\"\n            );\n        }\n\n        // Capture strategy-owned values before adding the strategy, which moves it\n        let strategy_id = self\n            .kernel\n            .trader\n            .borrow()\n            .prepare_strategy_for_registration(&mut strategy)?;\n        let oms_type = StrategyNative::strategy_core(&strategy).config.oms_type;\n        let instrument_ids = strategy.external_order_instrument_ids().unwrap_or_default();\n\n        if !instrument_ids.is_empty() {\n            self.register_external_order_claims(strategy_id, &instrument_ids)?;\n        }\n\n        let mut exec_engine = match oms_type","sourceCodeStart":2681,"sourceCodeEnd":2717,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/node/mod.rs#L2681-L2717","documentation":"add_strategy registers a trading strategy with the node and, like actor registration, is only permitted while the node is Idle. Calling it on a running node bails with this error to protect execution-engine invariants.","triggerScenarios":"Calling node.add_strategy(strategy) when node.state() != NodeState::Idle — after run/start has been called or while the node is starting/running.","commonSituations":"Strategies added in reaction to market data or user commands at runtime; setup code ordered after node.run(); configuration loading that completes asynchronously after start.","solutions":["Add all strategies before starting the node","Check node.state() == NodeState::Idle before calling in dynamic flows","For runtime strategy changes, use the execution engine's supported dynamic APIs rather than the node-level registration method"],"exampleFix":"// before\nnode.run().await?;\nnode.add_strategy(my_strategy)?;\n// after\nnode.add_strategy(my_strategy)?;\nnode.run().await?;","handlingStrategy":"validation","validationCode":"if node.state() == NodeState::Idle {\n    node.add_strategy(strategy)?;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Load and register all strategies before run()","Guard dynamic strategy code paths with state checks","Keep strategy configuration synchronous and pre-start"],"tags":["rust","live-node","strategy","lifecycle","state"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}