nautechsystems/nautilus_trader · error
Strategy {strategy_id} is not registered with a trader
Error message
Strategy {strategy_id} is not registered with a trader What it means
set_external_order_instrument_ids requires the strategy to be registered with a running trader. The call bails when the underlying actor core reports is_registered() == false, because external order claims are recorded in the trader's cache under the registered strategy ID.
Source
Thrown at crates/trading/src/strategy/mod.rs:135
/// External orders, fills, and materialized reconciliation activity for matching instrument
/// IDs are assigned to the strategy. Passing an empty vector releases every claim owned by the
/// strategy. Existing cached orders keep their assigned strategy ID.
///
/// # Errors
///
/// Returns an error if the strategy is not registered, the cache is already borrowed, an
/// instrument is repeated, or an instrument is claimed by another strategy.
fn set_external_order_instrument_ids(
&mut self,
instrument_ids: Vec<InstrumentId>,
) -> anyhow::Result<()>
where
Self: StrategyNative,
{
let core = StrategyNative::strategy_core_mut(self);
let strategy_id = registered_strategy_id(core)?;
if !core.actor.is_registered() {
anyhow::bail!("Strategy {strategy_id} is not registered with a trader");
}
let cache = core.cache_rc();
cache
.try_borrow_mut()
.map_err(|e| anyhow::anyhow!("Cannot set external order claims: {e}"))?
.set_external_order_claims(strategy_id, &instrument_ids)?;
core.config.external_order_instrument_ids = Some(instrument_ids);
Ok(())
}
/// Returns the runtime strategy ID, when configured or registered.
fn strategy_id(&self) -> Option<StrategyId>
where
Self: StrategyNative,
{
StrategyNative::strategy_core(self).strategy_id()
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Move the set_external_order_instrument_ids call into on_start, after registration is guaranteed.
- Ensure the strategy is added to a TradingNode/BacktestEngine and the node is started before using the API.
- Guard the call with a registration check and defer it (e.g. schedule) until the strategy is registered.
Example fix
// before
class MyStrategy(Strategy):
def on_init(self, event):
self.set_external_order_instrument_ids([instrument_id])
// after
class MyStrategy(Strategy):
def on_start(self):
self.set_external_order_instrument_ids([instrument_id]) Defensive patterns
Strategy: validation
Validate before calling
if not strategy.is_registered:
raise RuntimeError("call set_external_order_instrument_ids only after the trader registers the strategy (on_start)") Type guard
def can_set_external_claims(strategy) -> bool:
return bool(getattr(strategy, "is_registered", False)) Try / catch
try:
self.set_external_order_instrument_ids(ids)
except RuntimeError as e:
if "not registered with a trader" in str(e):
self.log.warning("deferred external claims setup: strategy not yet registered")
else:
raise Prevention
- Perform trader-dependent setup in on_start, never in __init__ or on_init
- Always attach strategies to a TradingNode/BacktestEngine before exercising their APIs
- Check registration state before any call that touches the trader's cache
When it happens
Trigger: Calling set_external_order_instrument_ids before the strategy has been added to a trading node and the node/trader started — e.g. in __init__, on_init, or on a standalone strategy instance never attached to a trader.
Common situations: Calling the API in on_init instead of on_start; constructing a Strategy in isolation (unit test or script) without a BacktestEngine/TradingNode; node startup ordering where config code runs before registration.
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
- Cannot add strategy while node is running, add strategies be
- Strategy not registered: OrderFactory not initialized
- Strategy not registered: Portfolio not initialized
- Active execution intent {intent_id} was not found
- DataActor {} must be registered before calling `clock_mut()`
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f4ad418a89dc6aad.
Report an issue: GitHub.