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

  1. Move the set_external_order_instrument_ids call into on_start, after registration is guaranteed.
  2. Ensure the strategy is added to a TradingNode/BacktestEngine and the node is started before using the API.
  3. 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

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


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