{"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":2579,"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 strategy configures one or more external order claims and the request repeats\n    ///   an instrument, or either tier already contains a requested claim.\n    /// - The strategy configures one or more external order claims or an OMS type override,\n    ///   and the execution engine is already borrowed. A strategy configuring neither does\n    ///   not take the borrow and cannot fail this way.\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 claims = strategy.external_order_claims().unwrap_or_default();\n\n        // The engine borrow is only needed for claims or an OMS override; a\n        // strategy requiring neither must not fail on an unavailable borrow.\n        let mut exec_engine = if claims.is_empty() && oms_type.is_none() {\n            None\n        } else {","sourceCodeStart":2561,"sourceCodeEnd":2597,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/live/src/node/mod.rs#L2561-L2597","documentation":"add_strategy (crates/live/src/node/mod.rs:2567) registers a strategy with the trader, capturing its external order claims and OMS type before it is moved. The node must be NodeState::Idle: strategies subscribe on the msgbus and may claim orders in the execution engine, which cannot be wired safely mid-run. Any state past Idle bails with this error.","triggerScenarios":"Calling node.add_strategy(strategy) after the node started running or during shutdown; also triggered when code re-adds strategies to a node instance that already ran once.","commonSituations":"Dynamically deploying strategies in response to live signals; hosted apps loading strategy modules after launch; reusing a node across sessions and adding strategies in between.","solutions":["Register every strategy before run(), ideally through the node builder.","For strategy churn, pre-register all candidate strategies and gate their behavior with config/flags instead of registering live.","Build a new node with the full strategy set when the set must change.","Check node.state() == NodeState::Idle before add_strategy in generic hosting code."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"if node.state() != NodeState::Idle {\n    anyhow::bail!(\"cannot register strategies now; add strategies before running the node\");\n}\nnode.add_strategy(strategy)?;","typeGuard":null,"tryCatchPattern":"if let Err(e) = node.add_strategy(strategy) {\n    let msg = e.to_string();\n    if msg.contains(\"while node is running\") {\n        log::error!(\"strategy registration must complete before run()\");\n    }\n    return Err(e);\n}","preventionTips":["Register all strategies before run(), ideally via the node builder.","Gate dynamic behavior with config flags on pre-registered strategies instead of late adds.","Keep a startup checklist (cache DB, actors, strategies, exec algorithms) that finishes before run()."],"tags":["live-node","strategy","registration","lifecycle"],"backgroundTag":"invalid-lifecycle-state","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}