nautechsystems/nautilus_trader · error
Failed to get class {class_name}: {e}
Error message
Failed to get class {class_name}: {e} What it means
After successfully importing the module, create_importable_component fetches the component class with module.getattr(class_name). This error means the attribute (class name) does not exist on the imported module — or importing it as an attribute raised — so the actor/strategy/exec algorithm cannot be constructed.
Source
Thrown at crates/backtest/src/python/node.rs:484
"{path_field} must be in format 'module.path:ClassName'",
)));
};
if module_name.is_empty() || class_name.is_empty() || class_name.contains(':') {
return Err(to_pyvalue_err(format!(
"{path_field} must be in format 'module.path:ClassName'",
)));
}
log::info!("Importing {component_name} from module: {module_name} class: {class_name}");
Python::attach(|py| -> anyhow::Result<Py<PyAny>> {
let module = py
.import(module_name)
.map_err(|e| anyhow::anyhow!("Failed to import module {module_name}: {e}"))?;
let class = module
.getattr(class_name)
.map_err(|e| anyhow::anyhow!("Failed to get class {class_name}: {e}"))?;
let config_instance = create_config_instance(py, config_path, config)?;
let component = if let Some(config_obj) = config_instance {
class.call1((config_obj,))?
} else {
class.call0()?
};
Ok(component.unbind())
})
.map_err(to_pyruntime_err)
}
pub(crate) fn create_config_instance<'py>(
py: Python<'py>,
config_path: &str,
config: &HashMap<String, serde_json::Value>,
) -> anyhow::Result<Option<Bound<'py, PyAny>>> {
if config_path.is_empty() && config.is_empty() {
log::debug!("No config_path or empty config, using None");View on GitHub (pinned to 18893faf8b)
Solutions
- Check the class name string in the config matches the top-level class exactly (case-sensitive).
- Confirm the class is defined at module scope, not nested in a function or another module.
- Run `python -c "from <module> import <class>"` to reproduce the exact getattr failure.
- Update stale configs after refactors/renames of the strategy or actor class.
Example fix
# before config = MyStrategyConfig(module="strategies.my_strategy", class_name="MyStrat") # renamed # after config = MyStrategyConfig(module="strategies.my_strategy", class_name="MyStrategy")
Defensive patterns
Strategy: validation
Validate before calling
import importlib
def assert_class_exists(module_name: str, class_name: str):
mod = importlib.import_module(module_name)
assert hasattr(mod, class_name), f"{module_name} has no attribute {class_name}"
assert_class_exists(config.module, config.class_name)
Try / catch
try:
node.add_strategy_from_config(strategy_config)
except Exception as e:
if "Failed to get class" in str(e):
raise SystemExit(f"Class name mismatch in config: {e}") from e
raise
Prevention
- Keep class names in configs generated from the classes themselves (avoid hand-typed strings).
- Grep configs after refactors/renames of strategy or actor classes.
- Respect Python casing: class names are case-sensitive in getattr.
When it happens
Trigger: py_add_actor_from_config / py_add_strategy_from_config / py_add_exec_algorithm_from_config with a config whose class name is misspelled, is not defined at module top level, or was renamed in a newer version of the user's code.
Common situations: Renaming the strategy class but not the config; class defined inside a function or submodule (e.g. strategies.my_strategy.MyStrategy vs strategies.MyStrategy); typos in casing ('myStrategy' vs 'MyStrategy').
Related errors
- Failed to import module {module_name}: {e}
- BacktestEngineConfig.controller for importable controller '{
- Failed to import config module {config_module_name}: {e}
- Failed to get config class {config_class_name}: {e}
- Failed to import config module {config_module_name}: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a487fd35e92fbd53.
Report an issue: GitHub.