nautechsystems/nautilus_trader · error

Already running

Error message

Already running

What it means

LiveNode::run_with_mode (crates/live/src/node/mod.rs:914) drives the full node lifecycle and is single-shot: it checks state().is_running() and bails with "Already running" if the node is currently running. A companion check rejects a second run after the runner was consumed, so a node instance can only ever be run once to completion.

Source

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

    /// # Errors
    ///
    /// Returns an error if the node fails to start or encounters a runtime error.
    pub async fn run(&mut self) -> anyhow::Result<()> {
        self.run_with_mode(NodeRunMode::Owned).await
    }

    /// Run the live node under the given mode.
    ///
    /// [`NodeRunMode::Hosted`] leaves signal handling to the host application. Every other
    /// responsibility, including maintenance, reconciliation, external ingress, and the shutdown
    /// sequence, is identical across modes so that hosted and owned nodes cannot diverge.
    ///
    /// # Errors
    ///
    /// Returns an error if the node fails to start or encounters a runtime error.
    pub async fn run_with_mode(&mut self, mode: NodeRunMode) -> anyhow::Result<()> {
        if self.state().is_running() {
            anyhow::bail!("Already running");
        }

        if self.runner.is_none() {
            anyhow::bail!("Runner already consumed - run() called twice");
        }

        self.prepare_cache().await?;

        let Some(runner) = self.runner.take() else {
            anyhow::bail!("Runner already consumed - run() called twice");
        };
        runner.bind_senders();

        let AsyncRunnerChannels {
            mut time_evt_rx,
            mut system_evt_rx,
            mut system_cmd_rx,
            mut exec_evt_rx,

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Call run()/run_with_mode() exactly once per node instance; build and configure a fresh node for another session.
  2. Guard the call with the node's state (e.g. skip when it reports running).
  3. In hosted mode, ensure only the host drives run_with_mode and application code never calls run() itself.
  4. Distinguish this from the follow-up error "Runner already consumed - run() called twice": after a completed run the node is not reusable at all.

Example fix

// before
node.run().await?; // called again elsewhere -> "Already running"

// after
if !node.state().is_running() {
    node.run().await?;
} else {
    log::warn!("node already running, skipping duplicate run");
}
Defensive patterns

Strategy: validation

Validate before calling

if !node.state().is_running() {
    node.run_with_mode(mode).await?;
} else {
    log::warn!("node already running; skipping duplicate run");
}

Try / catch

match node.run().await {
    Ok(()) => {}
    Err(e) if e.to_string() == "Already running" => {
        log::warn!("run() called on an active node; ignoring");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling node.run() or node.run_with_mode(mode) a second time while the first run is still active; hosted integrations calling run_with_mode(NodeRunMode::Hosted) while an owned run() is in flight on the same node; retry wrappers re-invoking run() after an error while the node is still up.

Common situations: Error-handling retry loops around node.run(); re-running a notebook cell that calls run() on the same node object; hosting frameworks starting the node from two places; trying to restart a node after shutdown instead of building a new one.

Related errors


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