{"record":{"id":"28f66d324dc85f83","repo":"nautechsystems/nautilus_trader","slug":"failed-to-extract-pystrategy-e","errorCode":null,"errorMessage":"Failed to extract PyStrategy: {e}","messagePattern":"Failed to extract PyStrategy: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/system/src/python/registration.rs","lineNumber":214,"sourceCode":"        self.validate_actor_or_strategy_registration()?;\n\n        let existing_order_id_tags: Vec<&str> =\n            self.strategy_ids.iter().map(StrategyId::get_tag).collect();\n\n        let strategy_id = Python::attach(|py| -> anyhow::Result<StrategyId> {\n            let bound = strategy.bind(py);\n\n            let config_instance = bound\n                .getattr(\"config\")\n                .ok()\n                .filter(|config| !config.is_none());\n\n            let class_name = bound.get_type().name()?.to_string();\n\n            let mut py_strategy_ref = bound\n                .extract::<PyRefMut<PyStrategy>>()\n                .map_err(Into::<PyErr>::into)\n                .map_err(|e| anyhow::anyhow!(\"Failed to extract PyStrategy: {e}\"))?;\n\n            if let Some(config_obj) = config_instance.as_ref() {\n                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            };","sourceCodeStart":196,"sourceCodeEnd":232,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registration.rs#L196-L232","documentation":"`prepare_python_strategy_instance` extracts the supplied Python strategy object into `PyRefMut<PyStrategy>` to configure it. PyO3 extraction fails unless the object's class inherits from the Rust-backed `PyStrategy` base (`nautilus_trader.trading.strategy.Strategy`), producing this error.","triggerScenarios":"Calling `add_python_strategy_instance` (via trader add_strategy) with a Python object that does not subclass `Strategy` — e.g. a plain class with the right method names, a config, or an object of an incompatible strategy base.","commonSituations":"Custom strategy forgetting to inherit `nautilus_trader.trading.strategy.Strategy`; passing a StrategyConfig instead of the strategy instance; mixing strategy classes from different nautilus_trader versions.","solutions":["Make the strategy class inherit from `nautilus_trader.trading.strategy.Strategy`.","Pass the instantiated strategy object (not the class or config) to the add-strategy API.","Confirm the strategy and nautilus_trader Rust core come from the same installed version."],"exampleFix":"// before\nclass MyStrategy:\n    def on_start(self): ...\n\n// after\nfrom nautilus_trader.trading.strategy import Strategy\n\nclass MyStrategy(Strategy):\n    def on_start(self): ...","handlingStrategy":"type-guard","validationCode":"from nautilus_trader.trading.strategy import Strategy\nassert isinstance(my_strategy, Strategy), \"strategy must subclass Strategy\"","typeGuard":"def is_strategy(obj) -> bool:\n    from nautilus_trader.trading.strategy import Strategy\n    return isinstance(obj, Strategy)","tryCatchPattern":"try:\n    trader.add_strategy(strategy)\nexcept Exception as e:\n    if \"Failed to extract PyStrategy\" in str(e):\n        raise TypeError(f\"{type(strategy).__name__} must subclass nautilus_trader Strategy\") from e\n    raise","preventionTips":["Always subclass nautilus_trader.trading.strategy.Strategy.","Add an isinstance check in factory/factory-from-config code before adding strategies.","Keep one nautilus_trader version in the environment."],"tags":["python","pyo3","strategy","type-mismatch"],"backgroundTag":"type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}