nautechsystems/nautilus_trader · error

Cannot add execution algorithms to running trader

Error message

Cannot add execution algorithms to running trader

What it means

validate_exec_algorithm_registration permits exec algorithm registration only in PreInitialized, Ready, or Stopped states. Adding an execution algorithm while the trader is Running is rejected because the algorithm's msgbus endpoint and subscription hooks must be installed before the trader starts routing orders.

Source

Thrown at crates/system/src/trader.rs:850

            | ComponentState::Ready
            | ComponentState::Starting
            | ComponentState::Stopped
            | ComponentState::Running => Ok(()),
            ComponentState::Disposed => {
                anyhow::bail!("Cannot add components to disposed trader")
            }
            _ => anyhow::bail!("Cannot add components in current state: {}", self.state),
        }
    }

    /// Validates that the trader is in a valid state for execution algorithm registration.
    pub(crate) fn validate_exec_algorithm_registration(&self) -> anyhow::Result<()> {
        match self.state {
            ComponentState::PreInitialized | ComponentState::Ready | ComponentState::Stopped => {
                Ok(())
            }
            ComponentState::Running => {
                anyhow::bail!("Cannot add execution algorithms to running trader")
            }
            ComponentState::Disposed => {
                anyhow::bail!("Cannot add components to disposed trader")
            }
            _ => anyhow::bail!(
                "Cannot add execution algorithms in current state: {}",
                self.state
            ),
        }
    }

    /// Starts all registered components.
    ///
    /// # Errors
    ///
    /// Returns an error if any component fails to start.
    pub fn start_components(&mut self) -> anyhow::Result<()> {
        let actor_ids = self.actor_ids.clone();

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Register all exec algorithms before calling trader.start() (PreInitialized/Ready).
  2. If restarting is acceptable: stop the trader (Stopped allows registration), add the algorithm, then start again.
  3. Preload algorithms from config during setup instead of registering them on demand at runtime.

Example fix

// before
trader.start()?;
trader.add_exec_algorithm(algo)?; // bails: running

// after
trader.add_exec_algorithm(algo)?; // before start
trader.start()?;
Defensive patterns

Strategy: validation

Validate before calling

if trader.state == ComponentState::Running {
    // defer registration until stopped, or preload before start
}

Type guard

fn accepts_exec_algorithm(state: &ComponentState) -> bool {
    matches!(state, ComponentState::PreInitialized | ComponentState::Ready | ComponentState::Stopped)
}

Try / catch

match trader.add_exec_algorithm(algo) {
    Err(e) if e.to_string().contains("running trader") => {
        trader.stop()?;
        trader.add_exec_algorithm(algo)?;
        trader.start()?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling add_exec_algorithm (directly or via add_py_execution_algorithm_instance) while trader.state == ComponentState::Running — e.g. loading an algorithm mid-run or in a live callback.

Common situations: Attempting hot-loading of exec algorithms in a live trading session; a config loader that runs after trader.start(); background tasks lazily registering algorithms once the engine is already trading.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/29e456e2c76ae5e5. Report an issue: GitHub.