Skip to content

[Bug]: ASGI instrumentation crashes with AttributeError on FastAPI ≥ 0.137.0 (_IncludedRouter has no attribute 'path') #906

Description

@remyap89

Problem Description

Summary

InstanaASGIMiddleware._collect_kvs raises AttributeError: '_IncludedRouter' object has no attribute 'path'
on every request when using FastAPI 0.141.1 with Instana 3.16.0.

The error is swallowed by the except Exception block and logged via logger.debug, so it is silent
by default. However when INSTANA_DEBUG=true is set (or the Instana agent calls update_log_level()
to re-enable DEBUG after startup), the traceback floods application logs on every incoming HTTP request.
Additionally, http.path_tpl is never set, so endpoint names disappear from Instana's service catalogue
and traces cannot be correlated to specific endpoints.

Environment

Component Version
instana 3.16.0
fastapi 0.141.1
starlette 1.7.0
Python 3.12.13

Steps to Reproduce

  1. Install instana==3.16.0 and fastapi==0.141.1
  2. Create a FastAPI app with at least one include_router() call
  3. Enable INSTANA_DEBUG=true
  4. Send any HTTP request to the app

Error

2026-09-27 23:47:33,601: DEBUG instana: ASGI collect_kvs:
Traceback (most recent call last):
File "/path/to/venv/lib64/python3.12/site-packages/instana/instrumentation/asgi.py", line 58, in _collect_kvs
span.set_attribute("http.path_tpl", route.path)
^^^^^^^^^^
AttributeError: '_IncludedRouter' object has no attribute 'path'

This error repeats on every single HTTP request to the app.

Root Cause

FastAPI 0.137.0 changed how routers added via include_router() are stored. Previously, routes were
copied into the app's route list as APIRoute objects with a .path attribute. From 0.137.0 onward,
they are stored as _IncludedRouter wrapper objects (see
fastapi/routing.py) that hold a
reference to the original router for lazy resolution. _IncludedRouter implements .matches() but has
no .path attribute, which is what _collect_kvs unconditionally accesses on line 58:

# instana/instrumentation/asgi.py  lines 56-58
for route in scope["app"].routes:
    if route.matches(scope)[0] == Match.FULL:
        span.set_attribute("http.path_tpl", route.path)  # ← crashes for _IncludedRouter

This also means http.path_tpl is never set for any endpoint defined via include_router(),
causing those endpoints to disappear from Instana's service catalogue entirely.

Proposed Fix

When a matched route has no .path, use _IncludedRouter._match(scope) to resolve the winning
_EffectiveRouteContext, whose .path is already fully prefixed (e.g. /api/v2/deployments/{id}).
This is the same internal resolution path FastAPI itself uses:

for route in scope["app"].routes:
    try:
        match, _ = route.matches(scope)
    except Exception:
        continue
    if match != Match.FULL:
        continue
    if hasattr(route, "path"):
        # Normal APIRoute — path is directly available
        span.set_attribute("http.path_tpl", route.path)
        break
    # _IncludedRouter (FastAPI 0.137.0+): resolve via _match()
    _match_fn = getattr(route, "_match", None)
    if callable(_match_fn):
        try:
            _, _, _, route_context = _match_fn(scope)
            if route_context is not None:
                ctx_path = getattr(route_context, "path", None) or getattr(
                    route_context, "frontend_prefix", None
                )
                if ctx_path:
                    span.set_attribute("http.path_tpl", ctx_path)
        except Exception:
            pass
    break

Additionally, the outer except Exception block should use a silent pass instead of
logger.debug(..., exc_info=True) for route resolution failures. Logging a full traceback
on every request when debug is enabled is disproportionate for a non-fatal telemetry enrichment step.

Impact

  • http.path_tpl is never populated for any endpoint behind include_router() — endpoint names are missing from Instana's service catalogue

  • When INSTANA_DEBUG=true is set, a full traceback is logged on every HTTP request, producing significant log noise that obscures real application errors

  • Affects all applications using FastAPI ≥ 0.137.0 with include_router() (which is the standard pattern for structuring FastAPI applications)

Minimal, Complete, Verifiable, Example

Install instana==3.16.0 and fastapi==0.141.1
Create a FastAPI app with at least one include_router() call
Enable INSTANA_DEBUG=true
Send any HTTP request to the app

Python Version

python 3.12

Python Modules

| Component | Version |
|---|---|
| `instana` | 3.16.0 |
| `fastapi` | 0.141.1 |
| `starlette` | 1.7.0 |
| Python | 3.12.13 |

Python Environment

Running inside a CP4D (Cloud Pak for Data) Kubernetes pod.
Instana is loaded via AUTOWRAPT_BOOTSTRAP=instana environment variable.
Python 3.11 / 3.12 (container image).

Key env vars relevant to this bug:
AUTOWRAPT_BOOTSTRAP=instana
INSTANA_SERVICE_NAME=datasift-api

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions