nautechsystems/nautilus_trader · error

Cannot add components to disposed trader

Error message

Cannot add components to disposed trader

What it means

validate_actor_or_strategy_registration allows adding components only in PreInitialized, Ready, Starting, Stopped, or Running states. Once the trader is Disposed, its resources are torn down and no new actors or strategies may be added, so any registration attempt fails with this message.

Source

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

        );

        Ok(())
    }

    /// Validates that the trader is in a valid state for actor and strategy registration.
    ///
    /// Actors and strategies can be added while the trader is `PreInitialized`, `Ready`,
    /// `Stopped`, or `Running`. This enables the [`Controller`](crate::controller::Controller)
    /// to add them at runtime.
    pub(crate) fn validate_actor_or_strategy_registration(&self) -> anyhow::Result<()> {
        match self.state {
            ComponentState::PreInitialized
            | 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!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Create a new Trader instance instead of reusing the disposed one.
  2. Move all add_actor/add_strategy calls before dispose(), typically right after construction or after stop() if restarting.
  3. Track trader state (e.g. check the component state) before registration calls.

Example fix

// before
trader.dispose();
trader.add_strategy(strategy)?; // bails: disposed

// after
trader.dispose();
let trader = Trader::new(trader_id, ...);
trader.add_strategy(strategy)?;
Defensive patterns

Strategy: validation

Validate before calling

if trader.state == ComponentState::Disposed {
    // create a new trader before adding components
}

Type guard

fn can_register(trader: &Trader) -> bool {
    !matches!(trader.state, ComponentState::Disposed)
}

Try / catch

match trader.add_strategy(strategy) {
    Err(e) if e.to_string().contains("disposed") => {
        let mut trader = Trader::new(trader_id, ...);
        trader.add_strategy(strategy)?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling add_actor, add_strategy, add_actor_from_importable_config, add_strategy_from_importable_config, or prepare_python_strategy_instance after trader.dispose() (or equivalent teardown) has moved the trader's state to ComponentState::Disposed.

Common situations: Reusing a trader across backtest runs without recreating it; calling add_strategy in shutdown/cleanup code that runs after dispose; long-lived services holding a disposed trader after a stop-and-dispose sequence.

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/bc512acb4fff1103. Report an issue: GitHub.