nautechsystems/nautilus_trader · error

ExecutionAlgorithm not registered: trader_id is not set

Error message

ExecutionAlgorithm not registered: trader_id is not set

What it means

Raised by `registered_trader_id` in the execution algorithm module when `ExecutionAlgorithmCore` has no `trader_id` set, meaning the algorithm is not (fully) registered with a running trader. Order-denying/submit/modify/cancel operations need the trader context to publish correctly attributed order events, so they fail with this error.

Source

Thrown at crates/trading/src/algorithm/mod.rs:1536

    }
}

impl std::error::Error for EmulatedOrderSubmissionError {}

fn publish_order_initialized(order: &OrderAny) {
    let event = OrderEventAny::Initialized(order.init_event().clone());
    publish_order_event(&event);
}

fn publish_order_event(event: &OrderEventAny) {
    let topic = format!("events.order.{}", event.strategy_id());
    msgbus::publish_order_event(topic.into(), event);
}

fn registered_trader_id(core: &ExecutionAlgorithmCore) -> anyhow::Result<TraderId> {
    DataActorNative::core(core)
        .trader_id()
        .ok_or_else(|| anyhow::anyhow!("ExecutionAlgorithm not registered: trader_id is not set"))
}

fn required_account_id(order: &OrderAny, operation: &str) -> anyhow::Result<AccountId> {
    order.account_id().ok_or_else(|| {
        anyhow::anyhow!(
            "Cannot generate {operation} event for {}: account_id is not set",
            order.client_order_id()
        )
    })
}

#[cfg(test)]
mod tests {
    use std::{cell::RefCell, rc::Rc};

    use nautilus_common::{
        actor::DataActor,
        cache::Cache,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the trader/system is started and the algorithm is registered before issuing submit/modify/cancel/deny calls
  2. Wait for the system to reach its running/ready state (await start completion) before routing orders through the algorithm
  3. Use the standard system builder/registration path so the algorithm receives its core context (trader_id) at initialization
  4. Check shutdown ordering — do not submit orders to an algorithm whose trader is already disposed

Example fix

// before
algo.submit_order(order); // algo not yet registered
// after
system.start().await;
assert!(system.is_running());
algo.submit_order(order);
Defensive patterns

Strategy: validation

Validate before calling

// only route orders through a registered, running algorithm
if !system.is_running() || !algo.is_registered() {
    return Err("algorithm not registered with running trader");
}

Type guard

fn can_route(algo: &ExecutionAlgorithm, system: &System) -> bool {
    algo.is_registered() && system.is_running()
}

Try / catch

match algo.submit_order(order) {
    Err(e) if e.to_string().contains("not registered: trader_id is not set") => {
        // await system.start() completion, then retry once
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling `deny_order`, `submit_order`, `modify_order`, or `cancel_order` on an `ExecutionAlgorithm` that was never initialized/registered by a trader — `DataActorNative::core(core).trader_id()` returns `None` because registration never set the trader context.

Common situations: Submitting an order to an algorithm before the system/trader has started; using an algorithm instance outside a configured trading system; ordering operations racing trader startup/shutdown; constructing the algorithm manually instead of via the system's registration path.

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