{"record":{"id":"e9fc5322f68524bd","repo":"agentscope-ai/agentscope","slug":"key","errorCode":null,"errorMessage":"{key}","messagePattern":"\\{key\\}","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"src/agentscope/_utils/_mixin.py","lineNumber":28,"sourceCode":"    def __getattr__(self, key: str) -> object:\n        \"\"\"Get a dictionary item through attribute-style access.\n\n        Args:\n            key (`str`):\n                The requested attribute name.\n\n        Returns:\n            `object`:\n                The value stored under ``key``.\n\n        Raises:\n            `AttributeError`:\n                If the dictionary does not contain ``key``.\n        \"\"\"\n        try:\n            return dict.__getitem__(self, key)\n        except KeyError as error:\n            raise AttributeError(key) from error\n","sourceCodeStart":10,"sourceCodeEnd":29,"githubUrl":"https://github.com/agentscope-ai/agentscope/blob/e90f1c7592896cc95f6e5ee506194f533378247d/src/agentscope/_utils/_mixin.py#L10-L29","documentation":"A dict-mixin class in agentscope exposes attribute-style access (obj.key) backed by dict.__getitem__. When the key is missing, the KeyError is converted to AttributeError with the key as the message, matching Python's protocol for __getattr__. This means typos in attribute access surface as AttributeError, not KeyError.","triggerScenarios":"Accessing obj.some_key as an attribute when the dict does not contain that key, e.g. msg.metadata.nonexistent or config.missing_field on classes using this mixin.","commonSituations":"Accessing fields that were never set (optional metadata), renaming of keys between agentscope versions, or mixing dict access (obj['key']) semantics with attribute access expectations.","solutions":["Use the checked form: value = obj.get('key', default) or 'key' in obj before attribute access","Verify the key exists in the dict before access (list(obj.keys()))","Check the agentscope changelog if the attribute was renamed in a version upgrade"],"exampleFix":"# before\nval = block.meta  # AttributeError if 'meta' absent\n\n# after\nval = block.get(\"meta\")  # returns None or default\n# or\nval = block.meta if \"meta\" in block else None","handlingStrategy":"validation","validationCode":"if \"key\" in obj:\n    value = obj.key\nelse:\n    value = default","typeGuard":"from typing import Any, TypeGuard\n\ndef has_key(obj: Any, key: str) -> bool:\n    return isinstance(obj, dict) and key in obj","tryCatchPattern":"try:\n    value = obj.some_key\nexcept AttributeError:\n    value = obj.get(\"some_key\", default)","preventionTips":["Prefer .get(key, default) over attribute access for optional fields","Use 'key' in obj membership checks before attribute-style access","Print/list available keys when debugging unfamiliar dict-backed objects"],"tags":["attributeerror","dict-access","key-missing","python"],"backgroundTag":"attribute-missing-on-mapping","analyzedSha":"e90f1c7592896cc95f6e5ee506194f533378247d","analyzedAt":"2026-08-28T18:24:12.087Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}