APM Agent language and version: Python - elastic-apm (6.26.1). The bug affects all current releases (≤ 6.26.1): the newest agent (6.26.1, 25 May 2026) predates FastAPI 0.137.0 (14 Jun 2026), so no released version handles it.
The breakage was triggered when an unpinned FastAPI dependency resolved to ≥ 0.137.0 on an image rebuild.
Is there anything special in your setup? Standard FastAPI app. Two relevant details: (1) we run FastAPI ≥ 0.137.0 (the trigger), and (2) we register routers via many app.include_router(...) calls. APM is enabled with app.add_middleware(ElasticAPM, ...). Nothing unusual in the APM transport/output.
Description of the problem including expected versus actual behavior:
Since FastAPI 0.137.0, the Starlette/FastAPI middleware raises AttributeError: '_IncludedRouter' object has no attribute 'path' on every request that matches a route registered via include_router(...), returning HTTP 500.
The middleware's get_route_name() → _get_route_name() (in elasticapm/contrib/starlette/_init_.py) iterates app.routes and reads route.path. FastAPI 0.137.0 ( ♻️ Refactor internals to preserve `APIRouter` and `APIRoute` instances by tiangolo · Pull Request #15745 · fastapi/fastapi · GitHub ) changed include_router() so app.routes no longer contains flat APIRoute objects with .path; it now contains _IncludedRouter wrappers that match lazily and have no .path ( 0.137.0: how to get all paths of a router? · fastapi/fastapi · Discussion #15782 · GitHub ).
Expected: 200; transaction named by the route template (e.g. GET /items).
Actual: 500 on every matched request — the agent's route-name resolution throws before the endpoint runs
Steps to reproduce:
- Install fastapi>=0.137.0 and elastic-apm.
- Create an app that includes a router and adds the ElasticAPM middleware (below).
- Send any request matching a route in the included router → 500.
from elasticapm.contrib.starlette import ElasticAPM, make_apm_client
from fastapi import APIRouter, FastAPI
from starlette.testclient import TestClient
router = APIRouter()
@router.get("/items")
def items():
return {"ok": True}
app = FastAPI()
app.include_router(router) # FastAPI >=0.137 -> _IncludedRouter (no .path) in app.routes
apm = make_apm_client({"SERVICE_NAME": "repro", "DISABLE_SEND": True})
app.add_middleware(ElasticAPM, client=apm)
print(TestClient(app, raise_server_exceptions=False).get("/items").status_code)
# 500 on FastAPI >=0.137.0, 200 on <0.137.0
Provide logs and/or server output (if relevant):
File ".../elasticapm/contrib/starlette/__init__.py", line 244, in _request_started
transaction_name = self.get_route_name(request) or request.url.path
File ".../elasticapm/contrib/starlette/__init__.py", line 251, in get_route_name
route_name = self._get_route_name(scope, routes)
File ".../elasticapm/contrib/starlette/__init__.py", line 274, in _get_route_name
route_name = route.path
AttributeError: '_IncludedRouter' object has no attribute 'path'
Pinning Fast API pre 0.137.0 to avoid the issue for now. However, would be good if elastic-apm adopts FastAPI's new fastapi.routing.iter_route_contexts() to fix the dependency issue or recurse into the wrapper's child routes like the existing Mount branch. Same break is hitting OpenTelemetry, prometheus-fastapi-instrumentator ( AttributeError: '_IncludedRouter' object has no attribute 'path' with FastAPI 0.137.0 · Issue #370 · trallnag/prometheus-fastapi-instrumentator · GitHub ), and vLLM ([Bug]: vLLM 0.23.0 API server returns HTTP 500 on /v1/models due to prometheus_fastapi_instrumentator AttributeError: '_IncludedRouter' object has no attribute 'path' · Issue #45596 · vllm-project/vllm · GitHub).