nautechsystems/nautilus_trader · error
Component {component_id} is already registered with trader {
Error message
Component {component_id} is already registered with trader {} What it means
The generic component-ID collision guard: thrown when the ComponentId (actor, strategy, or exec algorithm) you are registering is already tracked by this trader under any of `actor_ids`, `strategy_ids`, or `exec_algorithm_ids`. It prevents cross-kind ID collisions where, say, an actor and a strategy share the same identifier, which would break component lookup and message routing.
Source
Thrown at crates/system/src/python/registration.rs:476
/// live strategy would overwrite that strategy's clock, registry entries, and wrapper, and a
/// rollback would then remove state the attempt did not create. The lifecycle collections are
/// checked alongside the clocks because a component registered externally and tracked through
/// `add_*_id_for_lifecycle` has no trader-owned clock.
fn ensure_component_id_available(&self, component_id: ComponentId) -> anyhow::Result<()> {
let id = component_id.inner();
let tracked = self.clocks.contains_key(&component_id)
|| self.actor_ids.iter().any(|actor_id| actor_id.inner() == id)
|| self
.strategy_ids
.iter()
.any(|strategy_id| strategy_id.inner() == id)
|| self
.exec_algorithm_ids
.iter()
.any(|exec_algorithm_id| exec_algorithm_id.inner() == id);
if tracked {
anyhow::bail!(
"Component {component_id} is already registered with trader {}",
self.trader_id
);
}
Ok(())
}
}
fn create_python_actor(config: &ImportableActorConfig) -> anyhow::Result<(Py<PyAny>, ActorId)> {
let (module_name, class_name) = split_import_path(&config.actor_path, "actor_path")?;
log::info!("Importing actor from module: {module_name} class: {class_name}");
Python::attach(|py| -> anyhow::Result<(Py<PyAny>, ActorId)> {
let actor_class = import_python_class(py, module_name, class_name)?;
let config_instance = create_config_instance(py, &config.config_path, &config.config)?;
View on GitHub (pinned to 18893faf8b)
Solutions
- Rename the conflicting component so each ComponentId is globally unique on the trader
- Inspect `trader_id` and the existing ID sets to find the colliding component
- Move the component to a different trader instance if both registrations are intentional
- Consolidate duplicate config entries sharing one name
Example fix
// before
ActorConfig { name: 'Alpha' } // actor
StrategyConfig { name: 'Alpha' } // strategy -> ComponentId collision
// after
StrategyConfig { name: 'AlphaStrategy' } Defensive patterns
Strategy: validation
Validate before calling
all_ids = trader.actor_ids() + trader.strategy_ids() + trader.exec_algorithm_ids()
ids = [c.value for c in all_ids]
assert len(ids) == len(set(ids)), f"duplicate component ids: {ids}" Type guard
def component_id_is_free(trader, component_id) -> bool:
return component_id.value not in (
{c.value for c in trader.actor_ids()} |
{c.value for c in trader.strategy_ids()} |
{c.value for c in trader.exec_algorithm_ids()}
) Try / catch
try:
trader.add_actor(actor)
except ValueError as e:
if "already registered with trader" in str(e):
raise ConfigError(f"component name collision: {e}") from e
else:
raise Prevention
- Namespace component names by kind (e.g. 'AlphaActor', 'AlphaStrategy')
- Lint configs for duplicate names across all component sections before launch
- One trader per logically isolated component set
When it happens
Trigger: Calling add_python_actor_instance, prepare/commit_python_strategy_instance, or add_py/python_exec_algorithm_instance with a component whose ID equals an existing component of ANY kind on the trader (the same-kind duplicates get their own messages first; this fires for cross-kind collisions or after those checks pass).
Common situations: An actor named 'MyStrategy-001' colliding with a strategy ID; config files that reuse the same component name across actor/strategy/exec-algorithm sections; migrating components between kinds without renaming.
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
- Actor {actor_id} is already registered
- Strategy {strategy_id} is already registered
- Execution algorithm '{exec_algorithm_id}' is already registe
- A different simulation module extractor is already registere
- Custom data type "{type_name}" is not registered for Arrow e
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b192ce1a4b65f3ab.
Report an issue: GitHub.