nautechsystems/nautilus_trader · error

Execution algorithm '{exec_algorithm_id}' is already tracked

Error message

Execution algorithm '{exec_algorithm_id}' is already tracked by trader

What it means

add_exec_algorithm_id_for_lifecycle tracks an execution algorithm ID with the trader for lifecycle management and refuses IDs already tracked. Exec algorithms are singular per trader; a duplicate would create double lifecycle handling.

Source

Thrown at crates/system/src/trader.rs:422

        Ok(())
    }

    /// Adds an externally-registered execution algorithm ID to the trader for lifecycle management.
    ///
    /// The execution algorithm must already be registered in the global component and actor
    /// registries. This method only tracks the ID so the trader can manage the algorithm's
    /// lifecycle (start/stop/dispose).
    ///
    /// # Errors
    ///
    /// Returns an error if an execution algorithm with the same ID is already tracked.
    pub fn add_exec_algorithm_id_for_lifecycle(
        &mut self,
        exec_algorithm_id: ExecAlgorithmId,
    ) -> anyhow::Result<()> {
        if self.exec_algorithm_ids.contains(&exec_algorithm_id) {
            anyhow::bail!("Execution algorithm '{exec_algorithm_id}' is already tracked by trader");
        }

        self.exec_algorithm_ids.push(exec_algorithm_id);

        log::debug!(
            "Added exec algorithm ID '{exec_algorithm_id}' to trader {} for lifecycle management",
            self.trader_id
        );

        Ok(())
    }

    /// Adds an externally-registered strategy to the trader for lifecycle management
    /// and installs its order/position event subscriptions, stop hook, and control endpoint.
    ///
    /// The strategy must already be registered in the global component and actor
    /// registries. The generic parameter `T` must match the concrete type stored
    /// in those registries so that the typed event handlers can retrieve it.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Register each exec algorithm ID once; make registration idempotent.
  2. Ensure only one code path registers exec algorithm components.
  3. Rebuild the trader between runs instead of re-registering into it.

Example fix

// before
register_python_exec_algorithm_components(...)
register_python_exec_algorithm_components(...)  # second pass: duplicate id
// after
if !exec_algorithm_registered {
    register_python_exec_algorithm_components(...);
    exec_algorithm_registered = true;
}
Defensive patterns

Strategy: validation

Validate before calling

if trader.exec_algorithm_ids().contains(&exec_algorithm_id) {
    return Ok(()); // idempotent
}
trader.add_exec_algorithm_id_for_lifecycle(exec_algorithm_id)?;

Type guard

fn exec_algo_tracked(trader: &Trader, id: &ExecAlgorithmId) -> bool {
    trader.exec_algorithm_ids().contains(id)
}

Try / catch

match trader.add_exec_algorithm_id_for_lifecycle(id) {
    Err(e) if e.to_string().contains("already tracked by trader") => Ok(()),
    other => other,
}

Prevention

When it happens

Trigger: Calling the public add_exec_algorithm_id_for_lifecycle twice with the same ExecAlgorithmId, typically from register_python_exec_algorithm_components running more than once (module re-init, repeated node setup).

Common situations: Re-running kernel/node setup in the same process, registering the same exec algorithm in both a builder and a manual setup path, notebook cells re-executed.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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