nautechsystems/nautilus_trader · error
Failed to get class {class_name}: {e}
Error message
Failed to get class {class_name}: {e} What it means
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.
Source
Thrown at crates/live/src/python/node.rs:1182
// Extract module and class name from actor_path
let parts: Vec<&str> = config.actor_path.split(':').collect();
if parts.len() != 2 {
return Err(to_pyvalue_err(
"actor_path must be in format 'module.path:ClassName'",
));
}
let (module_name, class_name) = (parts[0], parts[1]);
log::info!("Importing actor from module: {module_name} class: {class_name}");
let (python_actor, actor_id) =
Python::attach(|py| -> anyhow::Result<(Py<PyAny>, ActorId)> {
let actor_module = py
.import(module_name)
.map_err(|e| anyhow::anyhow!("Failed to import module {module_name}: {e}"))?;
let actor_class = actor_module
.getattr(class_name)
.map_err(|e| anyhow::anyhow!("Failed to get class {class_name}: {e}"))?;
let config_instance =
create_config_instance(py, &config.config_path, &config.config)?;
let python_actor = if let Some(config_obj) = config_instance.as_ref() {
actor_class.call1((config_obj,))?
} else {
actor_class.call0()?
};
log::debug!("Created Python actor instance: {python_actor:?}");
let actor_id = prepare_python_actor(&python_actor, config_instance.as_ref())?;
Ok((python_actor.unbind(), actor_id))
})
.map_err(to_pyruntime_err)?;
View on GitHub (pinned to 18893faf8b)
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.
Example fix
# before config = ImportableActorConfig(module='strats.momentum', class_name='MomentumStrat') # after (class is actually named MomentumStrategy) config = ImportableActorConfig(module='strats.momentum', class_name='MomentumStrategy')
Defensive patterns
Strategy: validation
Validate before calling
# Verify the class exists before adding the actor
import importlib
mod = importlib.import_module(config.module)
assert hasattr(mod, config.class_name), f"{config.class_name!r} not found in {config.module}" Type guard
def actor_class_exists(module_name: str, class_name: str) -> bool:
import importlib
return hasattr(importlib.import_module(module_name), class_name) Try / catch
try:
node.add_actor(actor_config)
except Exception as e:
if "Failed to get class" in str(e):
logging.error("class %s missing in %s; check spelling/renames", actor_config.class_name, actor_config.module)
else:
raise Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Failed to import module {module_name}: {e}
- Failed to get class {class_name}: {e}
- Failed to get config class {config_class_name}: {e}
- Invalid `external_order_claims` type: {e}
- Invalid `external_order_claims` instrument ID {claim}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/73cd54ac9f6892b6.
Report an issue: GitHub.