{"record":{"id":"abee54900ff4709b","repo":"nautechsystems/nautilus_trader","slug":"invalid-strategy-id-type","errorCode":null,"errorMessage":"Invalid `strategy_id` type","messagePattern":"Invalid `strategy_id` type","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/python/registration.rs","lineNumber":662,"sourceCode":"        .call_method(\"loads\", (json_str,), None)?\n        .into_any())\n}\n\nfn configure_py_strategy(\n    strategy: &mut PyRefMut<'_, PyStrategy>,\n    config_obj: &Bound<'_, PyAny>,\n) -> anyhow::Result<()> {\n    if let Some(strategy_id) = config_obj\n        .getattr(\"strategy_id\")\n        .ok()\n        .filter(|value| !value.is_none())\n    {\n        let strategy_id = if let Ok(strategy_id) = strategy_id.extract::<StrategyId>() {\n            strategy_id\n        } else if let Ok(strategy_id_str) = strategy_id.extract::<String>() {\n            StrategyId::new_checked(&strategy_id_str)?\n        } else {\n            anyhow::bail!(\"Invalid `strategy_id` type\");\n        };\n        strategy.set_strategy_id(strategy_id)?;\n    }\n\n    if let Some(order_id_tag) = config_obj\n        .getattr(\"order_id_tag\")\n        .ok()\n        .filter(|value| !value.is_none())\n    {\n        let order_id_tag = order_id_tag\n            .extract::<String>()\n            .map_err(|e| anyhow::anyhow!(\"Invalid `order_id_tag` type: {e}\"))?;\n        strategy.set_order_id_tag(&order_id_tag)?;\n    }\n\n    if let Some(log_events) = extract_bool_config_attr(config_obj, \"log_events\") {\n        strategy.set_log_events(log_events);\n    }","sourceCodeStart":644,"sourceCodeEnd":680,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registration.rs#L644-L680","documentation":"configure_py_strategy extracts the `strategy_id` attribute from the Python strategy config object. It accepts a StrategyId or a string convertible via StrategyId::new_checked; any other Python type fails extraction and triggers this bail. It is a strict argument-type guard during strategy configuration.","triggerScenarios":"Passing a strategy config whose `strategy_id` attribute is None, an int, a different domain object (e.g. InstrumentId), or an invalid identifier string that even new_checked would have rejected earlier.","commonSituations":"Forgetting to set strategy_id on the config, assigning a raw int/enum, or copying an id object of the wrong type from another component.","solutions":["Set `strategy_id` on the config to a valid string like \"MyStrategy-001\" or a StrategyId instance.","Wrap plain strings with StrategyId before assignment if constructing in Python.","Check the config isn't passing None because of an unset dataclass field."],"exampleFix":"// before\nconfig = MyStrategyConfig(strategy_id=123)\n// after\nconfig = MyStrategyConfig(strategy_id=\"MyStrategy-001\")","handlingStrategy":"type-guard","validationCode":"if not isinstance(config.strategy_id, (str, StrategyId)):\n    raise TypeError(\"config.strategy_id must be a StrategyId or string\")","typeGuard":"def has_valid_strategy_id(config) -> bool:\n    sid = getattr(config, \"strategy_id\", None)\n    return isinstance(sid, str) and sid or isinstance(sid, StrategyId)","tryCatchPattern":"try:\n    trader.add_strategy(strategy)\nexcept Exception as e:\n    if \"Invalid `strategy_id` type\" in str(e):\n        raise ValueError(\"Set config.strategy_id to a 'Name-001' string\") from e\n    raise","preventionTips":["Always set strategy_id as a string like 'MyStrategy-001' in configs","Never assign ints, enums, or other domain objects to strategy_id","Centralize strategy id construction in one helper"],"tags":["python","type-mismatch","strategy","registration"],"backgroundTag":"type-mismatch","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"}