{"record":{"id":"df25e94ef6874077","repo":"nautechsystems/nautilus_trader","slug":"failed-to-extract-pydataactor-e-df25e9","errorCode":null,"errorMessage":"Failed to extract PyDataActor: {e}","messagePattern":"Failed to extract PyDataActor: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/python/node.rs","lineNumber":1558,"sourceCode":"                {\n                    if let Some(config_obj) = config_instance.as_ref() {\n                        py_exec_algorithm_ref.configure_from_py_config(config_obj)?;\n                    }\n\n                    py_exec_algorithm_ref.set_python_instance(&python_exec_algorithm)?;\n                    let actor_id = ActorId::new(py_exec_algorithm_ref.exec_algorithm_id().inner());\n\n                    return Ok((\n                        python_exec_algorithm.unbind(),\n                        Some(py_exec_algorithm_ref.clone()),\n                        actor_id,\n                    ));\n                }\n\n                let mut py_data_actor_ref = python_exec_algorithm\n                    .extract::<PyRefMut<PyDataActor>>()\n                    .map_err(Into::<PyErr>::into)\n                    .map_err(|e| anyhow::anyhow!(\"Failed to extract PyDataActor: {e}\"))?;\n\n                // Extract ID from config: prefer exec_algorithm_id, fall back to actor_id\n                if let Some(config_obj) = config_instance.as_ref() {\n                    let id_attr = config_obj\n                        .getattr(\"exec_algorithm_id\")\n                        .ok()\n                        .filter(|v| !v.is_none())\n                        .or_else(|| config_obj.getattr(\"actor_id\").ok().filter(|v| !v.is_none()));\n\n                    if let Some(id_value) = id_attr {\n                        let actor_id_val = if let Ok(eaid) = id_value.extract::<ExecAlgorithmId>() {\n                            ActorId::new(eaid.inner())\n                        } else if let Ok(aid) = id_value.extract::<ActorId>() {\n                            aid\n                        } else if let Ok(aid_str) = id_value.extract::<String>() {\n                            ActorId::new_checked(&aid_str)?\n                        } else {\n                            anyhow::bail!(\"Invalid `exec_algorithm_id`/`actor_id` type\");","sourceCodeStart":1540,"sourceCodeEnd":1576,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/python/node.rs#L1540-L1576","documentation":"Raised when the object constructed from the exec algorithm config cannot be extracted as PyRefMut<PyDataActor> — i.e. the instantiated class is not a v2 DataActor-backed Python exec algorithm. The node needs the native actor payload to configure and register it.","triggerScenarios":"add_exec_algorithm_from_config where the imported class instantiates into something that is not a nautilus_trader Actor/ExecAlgorithm (e.g. it subclasses only Actor, is a plain class, or the wrong class was pointed at).","commonSituations":"Pointing config_path at a Strategy or plain class instead of an ExecAlgorithm/DataActor subclass; custom exec algorithms not migrated to the v2 base classes; instantiating via a factory function returning the wrong type.","solutions":["Ensure the configured class subclasses nautilus_trader.trading.actor.DataActor / the v2 ExecAlgorithm base","Point config_path at the correct class (not a strategy or plain actor)","Rebuild nautilus_trader so the Rust extension matches the installed Python package","Instantiate the class directly in a REPL to check its MRO contains the native base"],"exampleFix":"// before\nconfig_path=\"myalgos.exec:MyPlainActor\"  # only subclasses object\n// after\nclass MyExec(ExecAlgorithm): ...\nconfig_path=\"myalgos.exec:MyExec\"","handlingStrategy":"type-guard","validationCode":"from nautilus_trader.common.actor import Actor  # and relevant ExecAlgorithm base\nobj = import_cls(config_path)\nassert any(\"ExecAlgorithm\" in c.__name__ or issubclass(obj, Actor) for c in type(obj).__mro__), \"not a v2 actor-based exec algorithm\"","typeGuard":"def is_actor_based(obj) -> bool:\n    from nautilus_trader.common.actor import Actor\n    return isinstance(obj, Actor)","tryCatchPattern":"try:\n    node.add_exec_algorithm_from_config(cfg)\nexcept Exception as e:\n    if \"Failed to extract PyDataActor\" in str(e):\n        raise TypeError(f\"{cfg.config_path} does not instantiate a v2 DataActor/ExecAlgorithm\") from e\n    raise","preventionTips":["Ensure configured exec algorithm classes subclass the v2 ExecAlgorithm/DataActor bases","Don't point config_path at Strategy or plain classes","Verify the instantiated object's MRO in a quick script before running live"],"tags":["pyo3","live-trading","exec-algorithm","type-mismatch"],"backgroundTag":"incompatible-source-type","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"}