nautechsystems/nautilus_trader · error · anyhow::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
create_config_instance imports a config class from Python by splitting config_path on ':'. NautilusTrader importable config paths must have exactly two segments: 'module.path:ClassName'. Any string without exactly one colon (zero colons, or two or more) is rejected.
Source
Thrown at crates/backtest/src/python/node.rs:508
};
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");
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
- Rewrite the path to exactly 'module.path:ClassName' — dots in the module, one colon before the class
- Strip any extra ':key' suffixes; pass extra data through the config object itself, not the path
- Log/inspect the config_path value before calling and validate it with a regex like r'^[\w.]+:[\w]+$'
Example fix
// before config_path = "nautilus_trader.examples.strategies.my_strategy:MyStrategyConfig:extra" // after config_path = "nautilus_trader.examples.strategies.my_strategy:MyStrategyConfig"
Defensive patterns
Strategy: validation
Validate before calling
import re
def validate_config_path(path):
if not isinstance(path, str) or not re.fullmatch(r"[\w.]+:[\w]+", path):
raise ValueError(f"config_path must be 'module.path:ClassName', was {path!r}")
return path Type guard
def is_valid_config_path(path) -> bool:
return isinstance(path, str) and path.count(':') == 1 and all(path.split(':')) Try / catch
try:
component = create_importable_component(config_path)
except ValueError as e:
log.error("Bad config_path %r: %s", config_path, e) Prevention
- Always use one colon between module and class: 'a.b.c:ClassName'
- Never embed extra data in the import path; put it in the config object
- Validate paths with a regex before persisting configs
- Copy fully-qualified names from Python (Class.__module__, Class.__qualname__)
When it happens
Trigger: Passing a config path like 'my_module.MyConfig' (dot instead of colon), 'my.module.Config:Subkey:Extra' (extra colons), or an empty/whitespace path fragment via create_importable_component.
Common situations: Copy-pasting a fully-qualified Python class name without converting the last dot to a colon; programmatic config generation producing module:Class:extra; typos in YAML/JSON component config.
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
- {field} must be in format 'module.path:ClassName'
- config_path must be in format 'module.path:ClassName', was {
- Failed to set attribute {key}: {setattr_err}
- Failed to create config instance. Tried kwargs: {kwargs_err}
- Failed to set attribute {key}: {setattr_err}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/34078d808ee61bc3.
Report an issue: GitHub.