{"record":{"id":"fe6cbbacf2128d4b","repo":"nautechsystems/nautilus_trader","slug":"failed-to-get-class-class-name-e","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/system/src/python/registration.rs","lineNumber":549,"sourceCode":"    if module_name.is_empty() || class_name.is_empty() || class_name.contains(':') {\n        anyhow::bail!(\"{field} must be in format 'module.path:ClassName'\");\n    }\n\n    Ok((module_name, class_name))\n}\n\nfn import_python_class<'py>(\n    py: Python<'py>,\n    module_name: &str,\n    class_name: &str,\n) -> anyhow::Result<Bound<'py, PyAny>> {\n    let module = py\n        .import(module_name)\n        .map_err(|e| anyhow::anyhow!(\"Failed to import module {module_name}: {e}\"))?;\n\n    module\n        .getattr(class_name)\n        .map_err(|e| anyhow::anyhow!(\"Failed to get class {class_name}: {e}\"))\n}\n\nfn create_config_instance<'py>(\n    py: Python<'py>,\n    config_path: &str,\n    config: &HashMap<String, serde_json::Value>,\n) -> anyhow::Result<Option<Bound<'py, PyAny>>> {\n    if config_path.is_empty() && config.is_empty() {\n        log::debug!(\"No config_path or empty config, using None\");\n        return Ok(None);\n    }\n\n    let Some((config_module_name, config_class_name)) = config_path.split_once(':') else {\n        anyhow::bail!(\"config_path must be in format 'module.path:ClassName', was {config_path}\");\n    };\n\n    if config_module_name.is_empty()\n        || config_class_name.is_empty()","sourceCodeStart":531,"sourceCodeEnd":567,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/system/src/python/registration.rs#L531-L567","documentation":"Fired when the Python module imported successfully but does not expose an attribute with the given class name while resolving an actor or strategy specification ('module.path:ClassName'). The input at fault is a registration field naming a class that does not exist in the specified module.","triggerScenarios":"Registering a Python actor/strategy with a `module:Class` string where the class name is misspelled, the class was renamed/moved to another module, or only an instance (not the class) is exposed under that name.","commonSituations":"Refactors renaming strategy classes while old JSON/YAML configs still reference the old name; referencing a function instead of a class; case mismatch (e.g. `myactor` vs `MyActor`).","solutions":["Check the class name in the config matches the exported class in the module exactly","Open the module and confirm the class is defined (or re-exported) at the top level","Update stale configs after renames","Import the module interactively and `dir()` it to list available class names"],"exampleFix":"// before\n{\"strategy\": \"my_strategy.MomentumStrat\"}  # class renamed\n// after\n{\"strategy\": \"my_strategy.MomentumStrategy\"}","handlingStrategy":"validation","validationCode":"import importlib\nmod = importlib.import_module(module_name)\nassert hasattr(mod, class_name), f\"{module_name} has no class {class_name}\"","typeGuard":null,"tryCatchPattern":"try:\n    trader.add_strategy(strategy_config)\nexcept Exception as e:\n    if \"Failed to get class\" in str(e):\n        logging.error(\"verify class name in config: %s\", e)\n    raise","preventionTips":["Grep the module for `class <Name>` when writing configs","Update configs whenever strategy classes are renamed","Use editor autocomplete on the module to copy exact class names"],"tags":["python","attribute-error","config"],"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-14T05:17:10.506Z"}