nautechsystems/nautilus_trader · error
config_path must be in format 'module.path:ClassName', was {
Error message
config_path must be in format 'module.path:ClassName', was {config_path} What it means
Config class loading expects `config_path` in the exact `module.path:ClassName` form (module and class separated by exactly one colon). If splitting on ':' does not yield exactly 2 parts, the path is malformed and the loader bails. This guards against paths with no colon or with extra colons.
Source
Thrown at crates/live/src/python/node.rs:1787
/// This constructor is shared by `add_actor_from_config` and `add_strategy_from_config`.
/// It handles:
/// 1. Importing the config class from the module path
/// 2. Converting the `HashMap<String, serde_json::Value>` to a Python dict
/// 3. Trying kwargs-first construction, falling back to default + setattr
/// 4. Calling `__post_init__` for dataclasses when using the setattr path
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 config_parts: Vec<&str> = config_path.split(':').collect();
if config_parts.len() != 2 {
anyhow::bail!("config_path must be in format 'module.path:ClassName', was {config_path}");
}
let (config_module_name, config_class_name) = (config_parts[0], config_parts[1]);
log::debug!(
"Importing config class from module: {config_module_name} class: {config_class_name}"
);
let config_module = py
.import(config_module_name)
.map_err(|e| anyhow::anyhow!("Failed to import config module {config_module_name}: {e}"))?;
let config_class = config_module
.getattr(config_class_name)
.map_err(|e| anyhow::anyhow!("Failed to get config class {config_class_name}: {e}"))?;
// Convert config dict to Python dict
let py_dict = PyDict::new(py);
for (key, value) in config {View on GitHub (pinned to 18893faf8b)
Solutions
- Use the format 'package.module:ClassName', e.g. 'my.strategies.config:MyConfig'.
- Ensure exactly one colon separates module path from class name.
- Verify the module is importable from the working directory / PYTHONPATH after fixing the format.
- Trim stray whitespace or quotes around config_path.
Example fix
// before config_path = "my.strategies.MyStrategyConfig" // after config_path = "my.strategies:MyStrategyConfig"
Defensive patterns
Strategy: validation
Validate before calling
def check_config_path(p: str):
parts = p.split(':')
assert len(parts) == 2 and parts[0] and parts[1], f"config_path must be 'module.path:ClassName', was {p!r}"
check_config_path(config_path) Type guard
def is_dotted_path(p: str) -> bool:
parts = p.split(':')
return len(parts) == 2 and all(parts) Try / catch
try:
node.build(...) # triggers config class loading
except Exception as e:
if "must be in format 'module.path:ClassName'" in str(e):
print("use 'package.module:Class' form")
raise Prevention
- Store config_path strings as explicit 'module:Class' constants.
- Write a unit test that imports the module via importlib before running the node.
- Beware of paths copied from docs that omit the colon.
When it happens
Trigger: Passing a config_path like "my.module.MyConfig" (no colon), "my.module:My:Config" (extra colon), or an empty/whitespace path to the node builder.
Common situations: Windows-style path confusion, copy-paste dropping the colon, or using a class name with a nested module path including extra colons.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
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/a2b40d6038419413.
Report an issue: GitHub.