{"id":"bc8a3c7c21374fcf","repo":"pallets/flask","slug":"after-this-request-can-only-be-used-when-a-reque","errorCode":null,"errorMessage":"'after_this_request' can only be used when a request context is active, such as in a view function.","messagePattern":"'after_this_request' can only be used when a request context is active, such as in a view function\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/flask/ctx.py","lineNumber":142,"sourceCode":"    request context, rather than during setup.\n\n    .. code-block:: python\n\n        @app.route(\"/\")\n        def index():\n            @after_this_request\n            def add_header(response):\n                response.headers[\"X-Foo\"] = \"Parachute\"\n                return response\n\n            return \"Hello, World!\"\n\n    .. versionadded:: 0.9\n    \"\"\"\n    ctx = _cv_app.get(None)\n\n    if ctx is None or not ctx.has_request:\n        raise RuntimeError(\n            \"'after_this_request' can only be used when a request\"\n            \" context is active, such as in a view function.\"\n        )\n\n    ctx._after_request_functions.append(f)\n    return f\n\n\nF = t.TypeVar(\"F\", bound=t.Callable[..., t.Any])\n\n\ndef copy_current_request_context(f: F) -> F:\n    \"\"\"Decorate a function to run inside the current request context. This can\n    be used when starting a background task, otherwise it will not see the app\n    and request objects that were active in the parent.\n\n    .. warning::\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/ctx.py#L124-L160","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\n@after_this_request  # module level -> RuntimeError\ndef add_header(response):\n    response.headers['X-Foo'] = 'Parachute'\n    return response\n\n# after\n@app.route('/')\ndef index():\n    @after_this_request\n    def add_header(response):\n        response.headers['X-Foo'] = 'Parachute'\n        return response\n    return 'Hello'","handlingStrategy":"type-guard","validationCode":"from flask import has_request_context, after_this_request\n\nif has_request_context():\n    @after_this_request\n    def add_header(response):\n        response.headers[\"X-Processed\"] = \"1\"\n        return response","typeGuard":"from flask import has_request_context\n\ndef can_register_after_request() -> bool:\n    return has_request_context()","tryCatchPattern":"try:\n    after_this_request(cleanup)\nexcept RuntimeError:\n    # Not in a request — run the cleanup directly instead\n    cleanup(None)","preventionTips":["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()`."],"tags":["flask","python","request-context","hooks"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}