nautechsystems/nautilus_trader · error
Failed to import module {module_name}: {e}
Error message
Failed to import module {module_name}: {e} What it means
Raised by `import_python_class` when `PyModule::import` fails to import the named Python module while resolving an actor or strategy class from its config (module path + class name). This is a Python ImportError translated into an anyhow error, meaning the module could not be found or raised an error during import.
Source
Thrown at crates/system/src/python/registration.rs:545
let Some((module_name, class_name)) = path.split_once(':') else {
anyhow::bail!("{field} must be in format 'module.path:ClassName'");
};
if module_name.is_empty() || class_name.is_empty() || class_name.contains(':') {
anyhow::bail!("{field} must be in format 'module.path:ClassName'");
}
Ok((module_name, class_name))
}
fn import_python_class<'py>(
py: Python<'py>,
module_name: &str,
class_name: &str,
) -> anyhow::Result<Bound<'py, PyAny>> {
let module = py
.import(module_name)
.map_err(|e| anyhow::anyhow!("Failed to import module {module_name}: {e}"))?;
module
.getattr(class_name)
.map_err(|e| anyhow::anyhow!("Failed to get class {class_name}: {e}"))
}
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");
return Ok(None);
}
let Some((config_module_name, config_class_name)) = config_path.split_once(':') else {
anyhow::bail!("config_path must be in format 'module.path:ClassName', was {config_path}");View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the module name in the config matches the importable Python module path exactly
- Run `python -c "import <module>"` in the same environment the trader uses to reproduce the ImportError
- Fix the underlying ImportError (install missing packages, correct relative/absolute path)
- Ensure the working directory / PYTHONPATH includes the package containing the module
Example fix
// before
{"actor": "my_stratPack.MyActor"} # module not importable
// after
{"actor": "my_strategy.actors.MyActor"} # correct dotted module path Defensive patterns
Strategy: validation
Validate before calling
import importlib importlib.import_module(module_name) # raises early with a clear ImportError
Try / catch
try:
trader.add_strategy(cfg)
except Exception as e:
if "Failed to import module" in str(e):
logging.error("check module path and Python environment: %s", e)
raise Prevention
- Test `python -c "import my_module"` in the exact runtime environment
- Use fully qualified dotted module paths in configs
- Activate the correct virtualenv before starting the trader
When it happens
Trigger: Registering a Python actor/strategy via a config with `actor`/`strategy` given as `module:Class` string where the module name is misspelled, not on `sys.path`, or the module itself raises ImportError at import time (e.g. missing dependency inside it).
Common situations: Typo in module path in a trader/backtest JSON config; running from a different working directory so a local module isn't importable; missing third-party dependency imported by the strategy module; virtualenv not active.
Related errors
- Failed to import config module {config_module_name}: {e}
- Invalid `external_order_claims` type: {e}
- Invalid `external_order_claims` instrument ID {claim}: {e}
- BacktestEngineConfig.controller for importable controller '{
- config_path must be in format 'module.path:ClassName', was {
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6a853545433b10ba.
Report an issue: GitHub.