nautechsystems/nautilus_trader · error
Failed to set attribute {key}: {setattr_err}
Error message
Failed to set attribute {key}: {setattr_err} What it means
When a default config class instance is created (kwargs construction failed), the loader sets each key from the config dict via Python `setattr`. If any attribute cannot be set (e.g. the dataclass field doesn't exist, the attribute is read-only/frozen, or the value type is incompatible), the code bails naming the key and the underlying setattr error.
Source
Thrown at crates/live/src/python/node.rs:1828
log::debug!("Created config dict: {py_dict:?}");
// Try kwargs first, then default constructor with setattr
let config_instance = match config_class.call((), Some(&py_dict)) {
Ok(instance) => {
log::debug!("Created config instance with kwargs");
instance
}
Err(kwargs_err) => {
log::debug!("Failed to create config with kwargs: {kwargs_err}");
match config_class.call0() {
Ok(instance) => {
log::debug!("Created default config instance, setting attributes");
for (key, value) in config {
let py_value = config_value_to_py(py, key, value)?;
if let Err(setattr_err) = instance.setattr(key, py_value) {
anyhow::bail!("Failed to set attribute {key}: {setattr_err}");
}
}
// Only call __post_init__ if it exists (setattr path
// needs it, kwargs path already triggered it via __init__)
if instance.hasattr("__post_init__")? {
instance.call_method0("__post_init__")?;
}
instance
}
Err(default_err) => {
anyhow::bail!(
"Failed to create config instance. \
Tried kwargs: {kwargs_err}, default: {default_err}"
);
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Check the named `{key}` exists as a writable field on the config class; remove or rename it if not.
- Un-freeze the config dataclass or drop keys targeting frozen fields.
- Match the value type to the field's expected type (e.g. pass a float not a string).
- Diff your config keys against the config class definition for the installed nautilus version.
Example fix
// before
config = {"bar_type": ..., "unknown_key": 1}
// after
config = {"bar_type": ...} Defensive patterns
Strategy: validation
Validate before calling
import importlib, inspect
mod, cls = config_path.split(':')
klass = getattr(importlib.import_module(mod), cls)
valid = {f for f in inspect.signature(klass.__init__).parameters} - {'self'}
bad = set(config) - valid
assert not bad, f"unknown config keys: {bad}" Type guard
def keys_match_config(config: dict, klass) -> bool:
import inspect
params = set(inspect.signature(klass.__init__).parameters)
return set(config) <= params Try / catch
try:
node.build(...)
except Exception as e:
if str(e).startswith("Failed to set attribute"):
key = str(e).split()[3]
print(f"drop or rename config key {key!r}")
raise Prevention
- Keep config keys in sync with the config class fields for your installed version.
- Prefer kwargs-constructible configs (avoid the setattr fallback path).
- Run a quick python -c 'MyConfig(**config)' smoke test before launching the node.
When it happens
Trigger: Providing a config key that is not an attribute of the config class, setting a field on a frozen dataclass, or passing a value Python rejects for a property setter (e.g. assigning to a slot-less read-only attr).
Common situations: Config dict keys renamed in a newer nautilus_trader version, typos in key names, or passing arbitrary extra keys the config class doesn't define.
Related errors
- Failed to set attribute {key}: {setattr_err}
- Failed to set attribute {key}: {setattr_err}
- Invalid `external_order_claims` type: {e}
- Invalid `external_order_claims` instrument ID {claim}: {e}
- BacktestEngineConfig.controller for importable controller '{
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/871634173ef61b88.
Report an issue: GitHub.