{"record":{"id":"094df830b42ce5f3","repo":"aio-libs/aiohttp","slug":"keyerror-key","errorCode":null,"errorMessage":"KeyError: {key}","messagePattern":"KeyError: (.+?)","errorType":"exception","errorClass":"KeyError","httpStatus":null,"severity":"error","filePath":"aiohttp/helpers.py","lineNumber":983,"sourceCode":"\n    def __init_subclass__(cls) -> None:\n        raise TypeError(\n            f\"Inheritance class {cls.__name__} from ChainMapProxy is forbidden\"\n        )\n\n    @overload  # type: ignore[override]\n    def __getitem__(self, key: AppKey[_T]) -> _T: ...\n\n    @overload\n    def __getitem__(self, key: str) -> Any: ...\n\n    def __getitem__(self, key: str | AppKey[_T]) -> Any:\n        for mapping in self._maps:\n            try:\n                return mapping[key]\n            except KeyError:\n                pass\n        raise KeyError(key)\n\n    @overload  # type: ignore[override]\n    def get(self, key: AppKey[_T], default: _S) -> _T | _S: ...\n\n    @overload\n    def get(self, key: AppKey[_T], default: None = ...) -> _T | None: ...\n\n    @overload\n    def get(self, key: str, default: Any = ...) -> Any: ...\n\n    def get(self, key: str | AppKey[_T], default: Any = None) -> Any:\n        try:\n            return self[key]\n        except KeyError:\n            return default\n\n    def __len__(self) -> int:\n        # reuses stored hash values if possible","sourceCodeStart":965,"sourceCodeEnd":1001,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/helpers.py#L965-L1001","documentation":"ChainMapProxy.__getitem__ raises KeyError when the requested key (a string or AppKey) is not found in any of the underlying mappings (request, route, app storage layers). ChainMapProxy searches each mapping in order and raises a plain KeyError if none contains the key. This is the standard key-not-found error for aiohttp Application/request storage.","triggerScenarios":"Accessing request['missing_key'] or app['missing_key'] where the key was never stored. Also triggered by using a string key when the data was stored under an AppKey, or vice versa. The key can be either a str or an AppKey[T] — they are not interchangeable lookups.","commonSituations":"Accessing a key set in a different middleware lifecycle phase that hasn't run yet; typo in the key name; mixing string keys with AppKey objects (storing with AppKey but retrieving with str); accessing cleanup context data before on_startup has run.","solutions":["Use .get(key, default) instead of __getitem__ to avoid the exception: value = request.app.get('key', default_value)","Verify the key was set in the correct lifecycle phase (on_startup, middleware, etc.)","Ensure you use the same key type for storage and retrieval (AppKey vs str)","Register the key in on_startup or middleware before any handler accesses it"],"exampleFix":"# before\nvalue = request.app['config']  # KeyError if 'config' not stored\n\n# after\nvalue = request.app.get('config')\nif value is None:\n    value = default_config\n    request.app['config'] = value\n\n# or with AppKey\nfrom aiohttp.web import AppKey\nconfig_key = AppKey('config', dict)\nvalue = request.app.get(config_key, {})","handlingStrategy":"try-catch","validationCode":"# Use .get() instead of [] for optional keys\nvalue = request.app.get(key)\nif value is None:\n    logger.debug('Key %r not found in app storage', key)\n    value = default_value\n\n# For required keys, validate at startup\nasync def on_startup(app):\n    for required_key in REQUIRED_KEYS:\n        if required_key not in app:\n            raise KeyError(f'Required key {required_key!r} missing from app storage')","typeGuard":"def key_exists(storage, key) -> bool:\n    try:\n        storage[key]\n        return True\n    except KeyError:\n        return False","tryCatchPattern":"try:\n    value = request.app[key]\nexcept KeyError:\n    log.warning('Key %r not in app storage, using default', key)\n    value = default_value","preventionTips":["Prefer .get(key, default) over __getitem__ for optional storage values","Validate required keys in on_startup hooks","Use AppKey consistently — do not mix str and AppKey for the same logical key","Document all keys your middleware sets and handlers expect"],"tags":["chainmap-proxy","key-error","application","storage","request"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}