{"record":{"id":"871634173ef61b88","repo":"nautechsystems/nautilus_trader","slug":"failed-to-set-attribute-key-setattr-err-871634","errorCode":null,"errorMessage":"Failed to set attribute {key}: {setattr_err}","messagePattern":"Failed to set attribute (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/live/src/python/node.rs","lineNumber":1828,"sourceCode":"    log::debug!(\"Created config dict: {py_dict:?}\");\n\n    // Try kwargs first, then default constructor with setattr\n    let config_instance = match config_class.call((), Some(&py_dict)) {\n        Ok(instance) => {\n            log::debug!(\"Created config instance with kwargs\");\n            instance\n        }\n        Err(kwargs_err) => {\n            log::debug!(\"Failed to create config with kwargs: {kwargs_err}\");\n\n            match config_class.call0() {\n                Ok(instance) => {\n                    log::debug!(\"Created default config instance, setting attributes\");\n                    for (key, value) in config {\n                        let py_value = config_value_to_py(py, key, value)?;\n\n                        if let Err(setattr_err) = instance.setattr(key, py_value) {\n                            anyhow::bail!(\"Failed to set attribute {key}: {setattr_err}\");\n                        }\n                    }\n\n                    // Only call __post_init__ if it exists (setattr path\n                    // needs it, kwargs path already triggered it via __init__)\n                    if instance.hasattr(\"__post_init__\")? {\n                        instance.call_method0(\"__post_init__\")?;\n                    }\n\n                    instance\n                }\n                Err(default_err) => {\n                    anyhow::bail!(\n                        \"Failed to create config instance. \\\n                         Tried kwargs: {kwargs_err}, default: {default_err}\"\n                    );\n                }\n            }","sourceCodeStart":1810,"sourceCodeEnd":1846,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/live/src/python/node.rs#L1810-L1846","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nconfig = {\"bar_type\": ..., \"unknown_key\": 1}\n// after\nconfig = {\"bar_type\": ...}","handlingStrategy":"validation","validationCode":"import importlib, inspect\nmod, cls = config_path.split(':')\nklass = getattr(importlib.import_module(mod), cls)\nvalid = {f for f in inspect.signature(klass.__init__).parameters} - {'self'}\nbad = set(config) - valid\nassert not bad, f\"unknown config keys: {bad}\"","typeGuard":"def keys_match_config(config: dict, klass) -> bool:\n    import inspect\n    params = set(inspect.signature(klass.__init__).parameters)\n    return set(config) <= params","tryCatchPattern":"try:\n    node.build(...)\nexcept Exception as e:\n    if str(e).startswith(\"Failed to set attribute\"):\n        key = str(e).split()[3]\n        print(f\"drop or rename config key {key!r}\")\n    raise","preventionTips":["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."],"tags":["python","setattr","config","dataclass"],"backgroundTag":"config-type-mismatch","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}