Skip to content

fix(django): Avoid ValueError in async middleware process_* hooks - #6698

Merged
alexander-alderman-webb merged 1 commit into
getsentry:masterfrom
r0ro:fix_django_async_middleware
Jun 30, 2026
Merged

fix(django): Avoid ValueError in async middleware process_* hooks#6698
alexander-alderman-webb merged 1 commit into
getsentry:masterfrom
r0ro:fix_django_async_middleware

Conversation

@r0ro

@r0ro r0ro commented Jun 30, 2026

Copy link
Copy Markdown
Contributor

Description

When an async Django middleware defines an async def hook such as process_view or process_exception, the SDK wrapped it in a synchronous function. That hid the coroutine from Django's iscoroutinefunction check in BaseHandler.load_middleware, so Django wrapped the hook in SyncToAsync and called it synchronously. The underlying coroutine was then never awaited, and the request failed with:

ValueError: The view ... didn't return an HttpResponse object.
            It returned an unawaited coroutine instead.

_get_wrapped_method in the Django middleware integration now produces an async def wrapper when the wrapped middleware hook is a coroutine function, instead of always producing a synchronous wrapper.

Issues

Discussed on Discord https://discord.com/channels/621778831602221064/1521260879218348103

@r0ro
r0ro requested a review from a team as a code owner June 30, 2026 13:47
@alexander-alderman-webb alexander-alderman-webb changed the title fix(django): fix wrapping of async middleware process_* hooks Jun 30, 2026
@alexander-alderman-webb
alexander-alderman-webb enabled auto-merge (squash) June 30, 2026 13:55
auto-merge was automatically disabled June 30, 2026 14:14

Head branch was pushed to by a user without write access

@r0ro
r0ro force-pushed the fix_django_async_middleware branch from 16903d3 to 42bb137 Compare June 30, 2026 14:14
@alexander-alderman-webb
alexander-alderman-webb enabled auto-merge (squash) June 30, 2026 14:16
When an async Django middleware defines an `async def` hook such as
`process_view` or `process_exception`, the SDK wrapped it in a synchronous
function. That hid the coroutine from Django's `iscoroutinefunction` check in
`BaseHandler.load_middleware`, so Django wrapped the hook in `SyncToAsync` and
called it synchronously. The underlying coroutine was then never awaited, and
the request failed with:

```
ValueError: The view ... didn't return an HttpResponse object.
            It returned an unawaited coroutine instead.
```

`_get_wrapped_method` in the Django middleware integration now produces an
`async def` wrapper when the wrapped middleware hook is a coroutine function,
instead of always producing a synchronous wrapper.
auto-merge was automatically disabled June 30, 2026 14:28

Head branch was pushed to by a user without write access

@r0ro
r0ro force-pushed the fix_django_async_middleware branch from 42bb137 to 8e9fb08 Compare June 30, 2026 14:28
@alexander-alderman-webb
alexander-alderman-webb enabled auto-merge (squash) June 30, 2026 14:42
@alexander-alderman-webb
alexander-alderman-webb merged commit 171aa16 into getsentry:master Jun 30, 2026
141 checks passed
mgaligniana pushed a commit to mgaligniana/sentry-python that referenced this pull request Aug 9, 2026
…getsentry#6698)

Stop wrapping async middleware hooks in sync functions to prevent misclassifications due to `iscoroutinefunction()` checks within Django.

Co-authored-by: Romain Fliedel <romain@oqee.tv>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants