{"id":"831e9463fb113e44","repo":"aio-libs/aiohttp","slug":"expected-one-of-the-following-apps-self-apps-r","errorCode":null,"errorMessage":"Expected one of the following apps {self._apps!r}, got {app!r}","messagePattern":"Expected one of the following apps (.+?), got (.+?)","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_urldispatcher.py","lineNumber":264,"sourceCode":"\n    def add_app(self, app: \"Application\") -> None:\n        if self._frozen:\n            raise RuntimeError(\"Cannot change apps stack after .freeze() call\")\n        if self._current_app is None:\n            self._current_app = app\n        self._apps.insert(0, app)\n\n    @property\n    def current_app(self) -> \"Application\":\n        app = self._current_app\n        assert app is not None\n        return app\n\n    @current_app.setter\n    def current_app(self, app: \"Application\") -> None:\n        if DEBUG:\n            if app not in self._apps:\n                raise RuntimeError(\n                    f\"Expected one of the following apps {self._apps!r}, got {app!r}\"\n                )\n        self._current_app = app\n\n    def freeze(self) -> None:\n        self._frozen = True\n\n    def __repr__(self) -> str:\n        return f\"<MatchInfo {super().__repr__()}: {self._route}>\"\n\n\nclass MatchInfoError(UrlMappingMatchInfo):\n\n    __slots__ = (\"_exception\",)\n\n    def __init__(self, http_exception: HTTPException) -> None:\n        self._exception = http_exception\n        super().__init__({}, SystemRoute(self._exception))","sourceCodeStart":246,"sourceCodeEnd":282,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/c0ef574e29109210e96e652771ae4e7b88615fa4/aiohttp/web_urldispatcher.py#L246-L282","documentation":"Raised as RuntimeError by the current_app setter on UrlMappingMatchInfo, but only when aiohttp's DEBUG flag is on. It checks that the app being set as current is one of the apps already in the match-info stack. In production (DEBUG off) the check is skipped, so this is a development-time invariant guard for the middleware/sub-app dispatch machinery.","triggerScenarios":"Triggered only with AIOHTTP_DEBUG/DEBUG enabled, when internal middleware dispatch (set_current_app context) tries to set current_app to an Application not in the resolved app stack. This is almost always an aiohttp-internal or middleware bug, not user-facing API misuse.","commonSituations":"Running with debug mode on and a buggy middleware that manipulates request.match_info.current_app; third-party middleware that incorrectly swaps current_app; version mismatch between aiohttp core and a middleware library.","solutions":["Treat this as a bug report candidate — check third-party middleware that touches match_info.current_app.","Update aiohttp and middleware libraries to matching compatible versions.","If reproducing in custom middleware, ensure you only set current_app to a value from match_info.apps.","File an issue with a minimal reproducer if it occurs with stock aiohttp."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"# Internal/debug guard — wrap suspect middleware dispatch in debug builds\ntry:\n    await handler(request)\nexcept RuntimeError as e:\n    if 'Expected one of the following apps' in str(e):\n        log.error(\"middleware set current_app to unknown app\")\n    raise","preventionTips":["Keep aiohttp and middleware libraries on compatible versions.","Avoid touching request.match_info.current_app in custom middleware.","Report reproducible occurrences as bugs."],"tags":["aiohttp","routing","sub-app","debug","internal"],"analyzedSha":"c0ef574e29109210e96e652771ae4e7b88615fa4","analyzedAt":"2026-08-04T19:51:05.467Z","schemaVersion":2}