{"record":{"id":"77ff0506b52aa61e","repo":"nautechsystems/nautilus_trader","slug":"cannot-add-actor-while-node-is-running-add-actors","errorCode":null,"errorMessage":"Cannot add actor while node is running, add actors before running the node","messagePattern":"Cannot add actor while node is running, add actors before running the node","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/node/mod.rs","lineNumber":2643,"sourceCode":"\n    /// Adds an actor to the trader.\n    ///\n    /// This method provides a high-level interface for adding actors to the underlying\n    /// trader without requiring direct access to the kernel. Actors should be added\n    /// after the node is built but before starting the node.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - The trader is not in a valid state for adding components.\n    /// - An actor with the same ID is already registered.\n    /// - The node is currently running.\n    pub fn add_actor<T>(&mut self, actor: T) -> anyhow::Result<()>\n    where\n        T: DataActor + DataActorNative + Component + Actor + 'static,\n    {\n        if self.state() != NodeState::Idle {\n            anyhow::bail!(\n                \"Cannot add actor while node is running, add actors before running the node\"\n            );\n        }\n\n        self.kernel.trader.borrow_mut().add_actor(actor)\n    }\n\n    /// Adds an actor to the live node using a factory function.\n    ///\n    /// The factory function is called at registration time to create the actor,\n    /// avoiding cloning issues with non-cloneable actor types.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if:\n    /// - The node is currently running.\n    /// - The factory function fails to create the actor.\n    /// - The underlying trader registration fails.","sourceCodeStart":2625,"sourceCodeEnd":2661,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/node/mod.rs#L2625-L2661","documentation":"Lifecycle guard in add_actor: components must be registered before the node runs; once the node is running the trader's message routing is live and adding an actor would bypass its start sequence, so the call bails.","triggerScenarios":"Calling node.add_actor(actor) when node.state() != NodeState::Idle — i.e. after start/run was invoked or during startup/running phases.","commonSituations":"Dynamically adding actors in response to runtime events; setup code accidentally executed after run(); test helpers (e.g. test_add_actor_registers_constructed_instance) calling add_actor on a node already progressed past Idle.","solutions":["Register all actors before calling run/start on the node","If dynamic composition is needed, create a separate node instance or defer to the appropriate engine API designed for runtime changes","Guard with a state check: only call add_actor when node.state() == NodeState::Idle"],"exampleFix":"// before\nnode.run().await?;\nnode.add_actor(my_actor)?;\n// after\nnode.add_actor(my_actor)?;\nnode.run().await?;","handlingStrategy":"validation","validationCode":"if node.state() == NodeState::Idle {\n    node.add_actor(actor)?;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register all actors before node.run()","Avoid runtime actor injection; redesign to pre-register","Add state assertions in setup helpers"],"tags":["rust","live-node","actor","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"}