nautechsystems/nautilus_trader · error

Cannot add actor while node is running, add actors before ru

Error message

Cannot add actor while node is running, add actors before running the node

What it means

add_actor (crates/live/src/node/mod.rs:2519) registers an actor with the trader's actor registry for data callbacks via the message bus. Registration must happen before the node runs, so the method rejects any state other than NodeState::Idle; once running, wiring a new actor into the msgbus and clock mid-session is unsafe.

Source

Thrown at crates/live/src/node/mod.rs:2523

    /// Adds an actor to the trader.
    ///
    /// This method provides a high-level interface for adding actors to the underlying
    /// trader without requiring direct access to the kernel. Actors should be added
    /// after the node is built but before starting the node.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - The trader is not in a valid state for adding components.
    /// - An actor with the same ID is already registered.
    /// - The node is currently running.
    pub fn add_actor<T>(&mut self, actor: T) -> anyhow::Result<()>
    where
        T: DataActor + DataActorNative + Component + Actor + 'static,
    {
        if self.state() != NodeState::Idle {
            anyhow::bail!(
                "Cannot add actor while node is running, add actors before running the node"
            );
        }

        self.kernel.trader.borrow_mut().add_actor(actor)
    }

    /// Adds an actor to the live node using a factory function.
    ///
    /// The factory function is called at registration time to create the actor,
    /// avoiding cloning issues with non-cloneable actor types.
    ///
    /// # Errors
    ///
    /// Returns an error if:
    /// - The node is currently running.
    /// - The factory function fails to create the actor.
    /// - The underlying trader registration fails.

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Register all actors during node construction, before run().
  2. Use the builder/factory registration path (add_actor_from_factory) at build time for non-cloneable actor types.
  3. If an actor is needed mid-session, design it as a pre-registered actor that activates/deactivates on messages instead of late registration.
  4. Build a fresh node if the actor set must change between sessions.

Example fix

// before
node.run().await?;
node.add_actor(my_actor)?; // bails: node not Idle

// after
node.add_actor(my_actor)?; // before running
node.run().await?;
Defensive patterns

Strategy: validation

Validate before calling

if node.state() != NodeState::Idle {
    anyhow::bail!("cannot register actors now; add actors before running the node");
}
node.add_actor(actor)?;

Try / catch

if let Err(e) = node.add_actor(actor) {
    if e.to_string().contains("while node is running") {
        log::error!("actor must be registered before run()");
    }
    return Err(e);
}

Prevention

When it happens

Trigger: Calling node.add_actor(actor) after the node has started running, during shutdown, or on any state != Idle; commonly from code inside on_start handlers or after run() returned.

Common situations: Strategies that spawn helper actors dynamically after start; hosted applications registering actors on an already-launched node; reusing a node and adding actors between runs.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21). Data as JSON: /api/errors/77ff0506b52aa61e. Report an issue: GitHub.