{"record":{"id":"cddd63c78e865cf4","repo":"nautechsystems/nautilus_trader","slug":"strategy-strategy-id-is-already-registered","errorCode":null,"errorMessage":"Strategy {strategy_id} is already registered","messagePattern":"Strategy (.+?) is already registered","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/python/registration.rs","lineNumber":235,"sourceCode":"                configure_py_strategy(&mut py_strategy_ref, config_obj)?;\n            }\n\n            // Mirrors the native path: a configured ID is kept, otherwise the runtime class name\n            // takes the configured order ID tag, or the next positional tag\n            let runtime_order_id_tag = py_strategy_ref.order_id_tag();\n            let strategy_id = if let Some(strategy_id) = py_strategy_ref.configured_strategy_id() {\n                strategy_id\n            } else {\n                let order_id_tag = normalize_order_id_tag(runtime_order_id_tag.as_deref())\n                    .map_or_else(\n                        || format!(\"{:03}\", existing_order_id_tags.len()),\n                        str::to_string,\n                    );\n                StrategyId::new_checked(format!(\"{class_name}-{order_id_tag}\"))?\n            };\n\n            if self.strategy_ids.contains(&strategy_id) {\n                anyhow::bail!(\"Strategy {strategy_id} is already registered\");\n            }\n            ensure_unique_order_id_tag(&existing_order_id_tags, strategy_id.get_tag())?;\n\n            py_strategy_ref.set_strategy_id(strategy_id)?;\n            py_strategy_ref.set_python_instance(bound)?;\n\n            Ok(py_strategy_ref.strategy_id())\n        })?;\n\n        // Rejected here as well as on commit so a caller which acts between the two phases, such\n        // as registering external order claims, does not act on a doomed registration\n        self.ensure_component_id_available(ComponentId::from(strategy_id))?;\n\n        Ok(strategy_id)\n    }\n\n    /// Commits a previously prepared Python strategy instance.\n    ///","sourceCodeStart":217,"sourceCodeEnd":253,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registration.rs#L217-L253","documentation":"Thrown by `prepare_python_strategy_instance` when the StrategyId derived from the strategy's class name and order_id_tag is already in the trader's `strategy_ids` set. Each strategy on a trader needs a unique ID because order IDs and client routing are keyed by it. Registration is aborted before the strategy is bound.","triggerScenarios":"Adding a second instance of the same strategy class without varying its `order_id_tag` (StrategyId defaults to `{class_name}-{order_id_tag}`); explicitly passing an order_id_tag that another strategy already uses.","commonSituations":"Running multiple instances of the same strategy class in one trader config but forgetting to set distinct `order_id_tag` values (e.g. two EmaCross strategies both tagged 001); programmatic loops that add the same configured strategy twice.","solutions":["Set a distinct `order_id_tag` on each strategy instance of the same class","Remove the duplicate strategy from your config or add-loop","Check `trader.strategy_ids` before adding and skip already-registered strategies","Use unique strategy config names if your builder derives the tag from config"],"exampleFix":"// before\nstrategy = MyStrategy(config)  # order_id_tag defaults to '001'\ntrader.add_strategy(strategy)\nstrategy2 = MyStrategy(config2)  # same tag -> duplicate id\ntrader.add_strategy(strategy2)\n// after\nstrategy2 = MyStrategy(config2 with order_id_tag='002')","handlingStrategy":"validation","validationCode":"used_tags = set()\nfor strat_cfg in strategy_configs:\n    tag = strat_cfg.order_id_tag\n    assert tag not in used_tags, f\"duplicate order_id_tag {tag}\"\n    used_tags.add(tag)","typeGuard":"def has_unique_tag(strategies: list) -> bool:\n    tags = [s.order_id_tag for s in strategies]\n    return len(tags) == len(set(tags))","tryCatchPattern":"try:\n    trader.add_strategy(strategy)\nexcept ValueError as e:\n    if \"Strategy\" in str(e) and \"already registered\" in str(e):\n        strategy.set_order_id_tag(next_free_tag())\n        trader.add_strategy(strategy)\n    else:\n        raise","preventionTips":["Always set an explicit order_id_tag when running multiple instances of one strategy class","Use a central counter or config registry to allocate tags","Test multi-instance setups in a sandbox trader before live deployment"],"tags":["rust","registration","duplicate-id","strategy"],"backgroundTag":"file-already-exists","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}