{"record":{"id":"73cd54ac9f6892b6","repo":"nautechsystems/nautilus_trader","slug":"failed-to-get-class-class-name-e-73cd54","errorCode":null,"errorMessage":"Failed to get class {class_name}: {e}","messagePattern":"Failed to get class (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/python/node.rs","lineNumber":1182,"sourceCode":"        // Extract module and class name from actor_path\n        let parts: Vec<&str> = config.actor_path.split(':').collect();\n        if parts.len() != 2 {\n            return Err(to_pyvalue_err(\n                \"actor_path must be in format 'module.path:ClassName'\",\n            ));\n        }\n        let (module_name, class_name) = (parts[0], parts[1]);\n\n        log::info!(\"Importing actor from module: {module_name} class: {class_name}\");\n\n        let (python_actor, actor_id) =\n            Python::attach(|py| -> anyhow::Result<(Py<PyAny>, ActorId)> {\n                let actor_module = py\n                    .import(module_name)\n                    .map_err(|e| anyhow::anyhow!(\"Failed to import module {module_name}: {e}\"))?;\n                let actor_class = actor_module\n                    .getattr(class_name)\n                    .map_err(|e| anyhow::anyhow!(\"Failed to get class {class_name}: {e}\"))?;\n\n                let config_instance =\n                    create_config_instance(py, &config.config_path, &config.config)?;\n\n                let python_actor = if let Some(config_obj) = config_instance.as_ref() {\n                    actor_class.call1((config_obj,))?\n                } else {\n                    actor_class.call0()?\n                };\n\n                log::debug!(\"Created Python actor instance: {python_actor:?}\");\n\n                let actor_id = prepare_python_actor(&python_actor, config_instance.as_ref())?;\n\n                Ok((python_actor.unbind(), actor_id))\n            })\n            .map_err(to_pyruntime_err)?;\n","sourceCodeStart":1164,"sourceCodeEnd":1200,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/python/node.rs#L1164-L1200","documentation":"Raised when the actor's module imports successfully but `getattr(class_name)` on the module fails, i.e. the expected actor class does not exist in that module. The `PyErr` (usually `AttributeError: module ... has no attribute ...`) is wrapped into this anyhow error with the class name included. This happens after the import step, so the module itself was found.","triggerScenarios":"Calling the node's add-actor API with a config whose `class_name` does not match any attribute of the module: misspelled class name, class defined in a submodule, class renamed in a version update, or the name refers to a non-class object.","commonSituations":"Copy-pasted config where the module was updated but the class name wasn't; renaming a strategy class without updating the YAML/JSON config; pointing at `package.file` but expecting the class at package level; typos in case-sensitive names.","solutions":["Confirm the class exists: `python -c \"import <module>; print(<module>.<class_name>)\"`.","Fix the `class_name` in the actor config to match the definition exactly (case-sensitive).","If the class moved, re-export it at module level (`from .impl import MyClass`) or update the config path.","Check for typos and recent renames after upgrading the codebase."],"exampleFix":"# before\nconfig = ImportableActorConfig(module='strats.momentum', class_name='MomentumStrat')\n# after (class is actually named MomentumStrategy)\nconfig = ImportableActorConfig(module='strats.momentum', class_name='MomentumStrategy')","handlingStrategy":"validation","validationCode":"# Verify the class exists before adding the actor\nimport importlib\nmod = importlib.import_module(config.module)\nassert hasattr(mod, config.class_name), f\"{config.class_name!r} not found in {config.module}\"","typeGuard":"def actor_class_exists(module_name: str, class_name: str) -> bool:\n    import importlib\n    return hasattr(importlib.import_module(module_name), class_name)","tryCatchPattern":"try:\n    node.add_actor(actor_config)\nexcept Exception as e:\n    if \"Failed to get class\" in str(e):\n        logging.error(\"class %s missing in %s; check spelling/renames\", actor_config.class_name, actor_config.module)\n    else:\n        raise","preventionTips":["Keep config class names in sync with code via tests that instantiate every configured class","Re-export classes at package level when moving them between modules","Use one config source of truth instead of duplicated YAML snippets","Remember Python names are case-sensitive; copy names from the class definition"],"tags":["python","attribute-error","class","live-node"],"backgroundTag":"class-not-found","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"}