nautechsystems/nautilus_trader · error
Cannot add strategy while node is running, add strategies be
Error message
Cannot add strategy while node is running, add strategies before running the node
What it means
add_strategy (crates/live/src/node/mod.rs:2567) registers a strategy with the trader, capturing its external order claims and OMS type before it is moved. The node must be NodeState::Idle: strategies subscribe on the msgbus and may claim orders in the execution engine, which cannot be wired safely mid-run. Any state past Idle bails with this error.
Source
Thrown at crates/live/src/node/mod.rs:2579
/// Strategies are registered in both the component registry (for lifecycle management)
/// and the actor registry (for data callbacks via msgbus).
///
/// # Errors
///
/// Returns an error if:
/// - The node is currently running.
/// - A strategy with the same ID is already registered.
/// - The strategy configures one or more external order claims and the request repeats
/// an instrument, or either tier already contains a requested claim.
/// - The strategy configures one or more external order claims or an OMS type override,
/// and the execution engine is already borrowed. A strategy configuring neither does
/// not take the borrow and cannot fail this way.
pub fn add_strategy<T>(&mut self, mut strategy: T) -> anyhow::Result<()>
where
T: Strategy + StrategyNative + DataActorNative + Component + Debug + 'static,
{
if self.state() != NodeState::Idle {
anyhow::bail!(
"Cannot add strategy while node is running, add strategies before running the node"
);
}
// Capture strategy-owned values before adding the strategy, which moves it
let strategy_id = self
.kernel
.trader
.borrow()
.prepare_strategy_for_registration(&mut strategy)?;
let oms_type = StrategyNative::strategy_core(&strategy).config.oms_type;
let claims = strategy.external_order_claims().unwrap_or_default();
// The engine borrow is only needed for claims or an OMS override; a
// strategy requiring neither must not fail on an unavailable borrow.
let mut exec_engine = if claims.is_empty() && oms_type.is_none() {
None
} else {View on GitHub (pinned to 2114cf6f76)
Solutions
- Register every strategy before run(), ideally through the node builder.
- For strategy churn, pre-register all candidate strategies and gate their behavior with config/flags instead of registering live.
- Build a new node with the full strategy set when the set must change.
- Check node.state() == NodeState::Idle before add_strategy in generic hosting code.
Defensive patterns
Strategy: validation
Validate before calling
if node.state() != NodeState::Idle {
anyhow::bail!("cannot register strategies now; add strategies before running the node");
}
node.add_strategy(strategy)?; Try / catch
if let Err(e) = node.add_strategy(strategy) {
let msg = e.to_string();
if msg.contains("while node is running") {
log::error!("strategy registration must complete before run()");
}
return Err(e);
} Prevention
- Register all strategies before run(), ideally via the node builder.
- Gate dynamic behavior with config flags on pre-registered strategies instead of late adds.
- Keep a startup checklist (cache DB, actors, strategies, exec algorithms) that finishes before run().
When it happens
Trigger: Calling node.add_strategy(strategy) after the node started running or during shutdown; also triggered when code re-adds strategies to a node instance that already ran once.
Common situations: Dynamically deploying strategies in response to live signals; hosted apps loading strategy modules after launch; reusing a node across sessions and adding strategies in between.
Related errors
- Cannot add actor while node is running, add actors before ru
- Cannot add exec algorithm while node is running, add exec al
- Already running
- Cannot set cache database while node is running, set it befo
- Binance Spot user data stream is not active
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/20b61ca63f2b3217.
Report an issue: GitHub.