Skip to content

fix(litestar): prepend CorrelationMiddleware so correlation context is established on all requests #729

Description

@cofin

Description

In sqlspec.extensions.litestar.SQLSpecPlugin.on_app_init, CorrelationMiddleware (and SQLCommenterMiddleware) is currently appended to app_config.middleware:

new_middlewares: list[DefineMiddleware] = []
if self._correlation_headers:
    new_middlewares.append(DefineMiddleware(CorrelationMiddleware, headers=self._correlation_headers))
if self._enable_sqlcommenter_middleware:
    new_middlewares.append(DefineMiddleware(SQLCommenterMiddleware))
if new_middlewares:
    app_config.middleware = [*(app_config.middleware or []), *new_middlewares]

The Problem

Because ASGI middleware stacks wrap earlier entries around later entries, appending CorrelationMiddleware places it as the innermost middleware (closest to route handlers), executing after authentication/security plugins, CORS, rate limiting, and session middleware.

If an outer middleware rejects a request early (such as litestar-security / auth guards returning 401 Unauthorized or 403 Forbidden, CORS rejection, or invalid session cookies), CorrelationMiddleware is never reached.

As a result:

  • CorrelationContext.get() remains None.
  • Downstream response logging (e.g. BeforeSendHandler / access loggers) and error hooks receive no correlation ID for rejected requests.

Expected Behavior

CorrelationMiddleware should run at the outer boundary of the application pipeline so that every incoming HTTP request generates or extracts a correlation ID immediately upon ingress, ensuring all access logs and early rejection responses have correlation context.

Proposed Fix

Prepend new_middlewares to app_config.middleware:

if new_middlewares:
    app_config.middleware = [*new_middlewares, *(app_config.middleware or [])]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions