{"record":{"id":"07de7e4ef270a844","repo":"nautechsystems/nautilus_trader","slug":"failed-to-extract-pystrategy-e-07de7e","errorCode":null,"errorMessage":"Failed to extract PyStrategy: {e}","messagePattern":"Failed to extract PyStrategy: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/python/node.rs","lineNumber":1254,"sourceCode":"            .node_mut()?\n            .kernel_mut()\n            .trader\n            .borrow_mut()\n            .prepare_python_strategy_instance(&strategy)\n            .map_err(to_pyruntime_err)?;\n\n        let (external_order_instrument_ids, oms_type) = Python::attach(\n            |py| -> anyhow::Result<(Option<Vec<InstrumentId>>, Option<OmsType>)> {\n                let bound = strategy.bind(py);\n                let config_obj = bound\n                    .getattr(\"config\")\n                    .ok()\n                    .filter(|config| !config.is_none());\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_obj.as_ref()\n                    && let Some(claims) =\n                        extract_external_order_instrument_ids_config_attr(config_obj)?\n                {\n                    py_strategy_ref.set_external_order_instrument_ids(Some(claims));\n                }\n\n                let claims = py_strategy_ref.external_order_instrument_ids();\n                let oms_type = config_obj\n                    .as_ref()\n                    .and_then(|cfg| cfg.getattr(\"oms_type\").ok())\n                    .filter(|value| !value.is_none())\n                    .and_then(|value| value.extract::<OmsType>().ok());\n\n                Ok((claims, oms_type))\n            },\n        )","sourceCodeStart":1236,"sourceCodeEnd":1272,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/python/node.rs#L1236-L1272","documentation":"Raised when the live node cannot extract a `PyRefMut<PyStrategy>` borrow from the Python strategy object during registration. This means the object registered as a strategy is not actually an instance of `PyStrategy` (or its Rust borrow cannot be taken, e.g. the object is already mutably borrowed in Python or is a different wrapper type). The registration aborts at this point.","triggerScenarios":"Registering a Python object as a strategy that is not a `PyStrategy` subclass instance (e.g. an Actor, a plain object, or a strategy built by a factory returning the wrong type), or extracting the borrow while the same object is already mutably borrowed elsewhere.","commonSituations":"Config `class_name` points to a class that subclasses `Actor` instead of `Strategy`; a custom factory wraps the strategy in a different container; passing the strategy class instead of an instance through a code path expecting a constructed `PyStrategy`.","solutions":["Verify the configured class subclasses `nautilus_trader.trading.strategy.Strategy` and is instantiated (not the class object itself).","Check what `{e}` reports: a `TypeError`/`ExtractErr` means wrong type; a `BorrowMutError` means the object is already checked out.","Ensure the factory/`create_config_instance` path returns the strategy instance directly.","Do not hold the strategy object mutably in Python code (e.g. inside a callback) while registering it."],"exampleFix":"# before\nclass MyActor(Actor):  # wrong base, extract as PyStrategy fails\n    ...\n# after\nfrom nautilus_trader.trading.strategy import Strategy\nclass MyStrategy(Strategy):\n    ...","handlingStrategy":"type-guard","validationCode":"# Ensure the configured object is a Strategy instance before registration\nfrom nautilus_trader.trading.strategy import Strategy\nobj = strategy_module(**config_kwargs)\nassert isinstance(obj, Strategy), f\"expected Strategy, got {type(obj).__name__}\"","typeGuard":"def is_py_strategy(obj) -> bool:\n    from nautilus_trader.trading.strategy import Strategy\n    return isinstance(obj, Strategy)","tryCatchPattern":"try:\n    node.trader.add_strategy(strategy)\nexcept Exception as e:\n    if \"Failed to extract PyStrategy\" in str(e):\n        logging.error(\"object is not a PyStrategy (check base class/instantiation): %s\", e)\n    else:\n        raise","preventionTips":["Subclass nautilus_trader.trading.strategy.Strategy (not Actor) for tradable strategies","Pass an instantiated strategy object, never the class itself","Ensure factory/config builders return the strategy instance directly","Avoid holding the strategy object mutably in Python during registration"],"tags":["python","pyo3","type-extraction","strategy"],"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"}