pallets/flask · error · RuntimeError
'after_this_request' can only be used when a request context
Error message
'after_this_request' can only be used when a request context is active, such as in a view function.
What it means
`after_this_request` registers a callback to run after only the current request, appending it to the active context's `_after_request_functions` (src/flask/ctx.py:139-148). It checks `_cv_app.get(None)` and requires the context to both exist and have a request (`ctx.has_request`); otherwise there is no 'this request' to attach the callback to, so it raises this RuntimeError. Note that in Flask 3.x an app context without a request also fails this check.
Source
Thrown at src/flask/ctx.py:142
request context, rather than during setup.
.. code-block:: python
@app.route("/")
def index():
@after_this_request
def add_header(response):
response.headers["X-Foo"] = "Parachute"
return response
return "Hello, World!"
.. versionadded:: 0.9
"""
ctx = _cv_app.get(None)
if ctx is None or not ctx.has_request:
raise RuntimeError(
"'after_this_request' can only be used when a request"
" context is active, such as in a view function."
)
ctx._after_request_functions.append(f)
return f
F = t.TypeVar("F", bound=t.Callable[..., t.Any])
def copy_current_request_context(f: F) -> F:
"""Decorate a function to run inside the current request context. This can
be used when starting a background task, otherwise it will not see the app
and request objects that were active in the parent.
.. warning::
View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Move the `after_this_request` registration inside a view function or a before-request hook, where a request context is active.
- If the behavior should apply to every request, use `@app.after_request` at setup time instead.
- In tests, wrap the call in `with app.test_request_context(): ...`.
- For background work, don't register per-request callbacks — operate on the response in the view before spawning the task.
Example fix
# before
@after_this_request # module level -> RuntimeError
def add_header(response):
response.headers['X-Foo'] = 'Parachute'
return response
# after
@app.route('/')
def index():
@after_this_request
def add_header(response):
response.headers['X-Foo'] = 'Parachute'
return response
return 'Hello' Defensive patterns
Strategy: type-guard
Validate before calling
from flask import has_request_context, after_this_request
if has_request_context():
@after_this_request
def add_header(response):
response.headers["X-Processed"] = "1"
return response Type guard
from flask import has_request_context
def can_register_after_request() -> bool:
return has_request_context() Try / catch
try:
after_this_request(cleanup)
except RuntimeError:
# Not in a request — run the cleanup directly instead
cleanup(None) Prevention
- Call `after_this_request` only from inside view functions or request-lifecycle hooks, never from background threads or startup code.
- For app-wide response mutation, register `app.after_request` at setup time instead of `after_this_request` per call.
- Guard shared helpers that conditionally register callbacks with `has_request_context()`.
When it happens
Trigger: Calling `after_this_request(fn)` (or using it as a decorator) outside request dispatch: at import time, in `before_first_request`-style setup code, inside a plain `with app.app_context()` block, in a CLI command, or in a background thread/task where the request ContextVar isn't propagated.
Common situations: Applying `@after_this_request` at module level or inside app setup instead of inside a view function; using it in Celery tasks or threads spawned from a view; unit-testing a helper that registers the callback without `app.test_request_context()`; trying to set response cookies from non-request code.
Related errors
- Working outside of request context. Attempted to use functi
- 'copy_current_request_context' can only be used when a reque
- There is no request in this context.
- Working outside of application context. Attempted to use fu
- The session is unavailable because no secret key was set. S
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/bc8a3c7c21374fcf.json.
Report an issue: GitHub ↗.