nautechsystems/nautilus_trader · error
Strategy {strategy_id} is already registered
Error message
Strategy {strategy_id} is already registered What it means
prepare_strategy_for_registration derives the final StrategyId (applying a per-strategy order id tag if given) and refuses to proceed if that id is already registered in trader.strategy_ids. This guard makes registration idempotent-safe: a strategy can only be registered once with the trader. It is the internal pre-check used by add_strategy.
Source
Thrown at crates/system/src/trader.rs:588
ensure_unique_order_id_tag(&existing_order_id_tags, strategy_id.get_tag())?;
StrategyNative::strategy_core_mut(strategy).change_id(strategy_id)?;
strategy_id
} else {
let order_id_tag = runtime_order_id_tag.map_or_else(
|| format!("{:03}", existing_order_id_tags.len()),
str::to_string,
);
ensure_unique_order_id_tag(&existing_order_id_tags, &order_id_tag)?;
let base_id = strategy_registration_id::<T>(strategy);
let strategy_id =
StrategyId::new_checked(format!("{}-{order_id_tag}", base_strategy_id(&base_id)))?;
StrategyNative::strategy_core_mut(strategy).change_id(strategy_id)?;
strategy_id
};
if self.strategy_ids.contains(&strategy_id) {
anyhow::bail!("Strategy {strategy_id} is already registered");
}
Ok(strategy_id)
}
/// Adds a strategy to the trader.
///
/// Strategies are registered in both the component registry (for lifecycle management)
/// and the actor registry (for data callbacks via msgbus). The strategy's `StrategyCore`
/// is also registered with the portfolio for order management.
///
/// # Errors
///
/// Returns an error if:
/// - The trader is not in a valid state for adding components.
/// - A strategy with the same ID is already registered.
pub fn add_strategy<T>(&mut self, mut strategy: T) -> anyhow::Result<()>
whereView on GitHub (pinned to 18893faf8b)
Solutions
- Check that the strategy's StrategyId is not already in trader.strategy_ids before calling add_strategy.
- Give each strategy a unique name and unique order_id_tag so resolved ids cannot collide.
- If re-registering after a restart, create a fresh trader or remove/dispose the old strategy first.
Example fix
// before
trader.add_strategy(strategy)?;
trader.add_strategy(strategy)?; // panics/bails second time
// after
let strategy_id = StrategyNative::strategy_core(&strategy).id().clone();
if !trader.strategy_ids.contains(&strategy_id) {
trader.add_strategy(strategy)?;
} Defensive patterns
Strategy: validation
Validate before calling
let strategy_id = StrategyNative::strategy_core(&strategy).id().clone();
if trader.strategy_ids.contains(&strategy_id) {
// skip or error early
} Try / catch
match trader.add_strategy(strategy) {
Err(e) if e.to_string().contains("already registered") => { /* idempotent skip */ }
other => other?,
} Prevention
- Ensure each strategy has a unique name and order_id_tag
- Deduplicate strategy configs before constructing strategies
- Wrap registration in an idempotent helper that checks strategy_ids first
When it happens
Trigger: Calling trader.add_strategy (directly or via prepare_strategy_for_registration) with a strategy whose resolved StrategyId already exists — e.g. adding the same strategy twice, or two strategies whose base name and order_id_tag resolve to the same id.
Common situations: Adding the same strategy object twice by accident in a loop over configs; duplicate order_id_tag values combined with identical strategy names producing colliding ids; re-running an init function without guarding against prior registration.
Related errors
- Strategy '{strategy_id}' is already tracked by trader
- Client already registered with ID {client_id}
- Venue {venue} already routed to {existing_client_id}, cannot
- Data client '{name}' is already registered
- Execution client '{name}' is already registered
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/691ec90a76fef777.
Report an issue: GitHub.