{"record":{"id":"489014cb915a8f4c","repo":"aio-libs/aiohttp","slug":"added-route-will-never-be-executed-method-route","errorCode":null,"errorMessage":"Added route will never be executed, method {route.method} is already registered","messagePattern":"Added route will never be executed, method (.+?) is already registered","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"aiohttp/web_urldispatcher.py","lineNumber":323,"sourceCode":"            raise HTTPExpectationFailed(text=\"Unknown Expect: %s\" % expect)\n\n\nclass Resource(AbstractResource):\n    def __init__(self, *, name: str | None = None) -> None:\n        super().__init__(name=name)\n        self._routes: dict[str, ResourceRoute] = {}\n        self._any_route: ResourceRoute | None = None\n        self._allowed_methods: set[str] = set()\n\n    def add_route(\n        self,\n        method: str,\n        handler: type[AbstractView] | Handler,\n        *,\n        expect_handler: _ExpectHandler | None = None,\n    ) -> \"ResourceRoute\":\n        if route := self._routes.get(method, self._any_route):\n            raise RuntimeError(\n                \"Added route will never be executed, \"\n                f\"method {route.method} is already \"\n                \"registered\"\n            )\n\n        route_obj = ResourceRoute(method, handler, self, expect_handler=expect_handler)\n        self.register_route(route_obj)\n        return route_obj\n\n    def register_route(self, route: \"ResourceRoute\") -> None:\n        assert isinstance(\n            route, ResourceRoute\n        ), f\"Instance of Route class is required, got {route!r}\"\n        if route.method == hdrs.METH_ANY:\n            self._any_route = route\n        self._allowed_methods.add(route.method)\n        self._routes[route.method] = route\n","sourceCodeStart":305,"sourceCodeEnd":341,"githubUrl":"https://github.com/aio-libs/aiohttp/blob/d041d4d0fd48c3f0832084d33be16cf1c4835f85/aiohttp/web_urldispatcher.py#L305-L341","documentation":"Resource.add_route refuses to register a second route for the same HTTP method (or for the catch-all ANY method) on the same Resource, because the second handler would be unreachable — the first registered route always wins. The check looks up self._routes.get(method) and also checks self._any_route. Raising early prevents silent shadowing where a developer believes two handlers both run but only one ever does.","triggerScenarios":"Calling resource.add_route('GET', h1) then resource.add_route('GET', h2) on the same Resource; or registering ANY handler (via add_route with method '*') and then a specific method. Also happens via app.router.add_get twice on the same path when they resolve to the same underlying Resource.","commonSituations":"Copy-pasting route registration and forgetting the first one exists; refactoring that moves routes without removing the originals; conditional registration that runs twice; building routes in a loop where a path collides.","solutions":["Remove or rename the duplicate registration so each (resource, method) pair has exactly one handler.","If you need different handlers, give the paths distinct templates or use distinct resource names.","Search the route table for the conflicting method/path before re-registering."],"exampleFix":"// before\nresource.add_route('GET', get_items)\nresource.add_route('GET', get_items_v2)  # RuntimeError\n// after\nresource.add_route('GET', get_items_v2)  # only register the one you want","handlingStrategy":"validation","validationCode":"def safe_add_route(resource, method, handler):\n    if method in getattr(resource, '_routes', {}):\n        raise RuntimeError(f'{method} already registered on this resource')\n    return resource.add_route(method, handler)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Centralize route registration in one module to avoid duplicates.","Use named resources and a registry so collisions are visible.","Add a startup self-test that asserts no duplicate (path, method) pairs."],"tags":["routing","duplicate","registration"],"backgroundTag":null,"analyzedSha":"d041d4d0fd48c3f0832084d33be16cf1c4835f85","analyzedAt":"2026-08-11T20:44:15.550Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}