pallets/flask · error · RuntimeError
Working outside of request context. Attempted to use functi
Error message
Working outside of request context. Attempted to use functionality that expected an active HTTP request. See the documentation on request context for more information.
What it means
The `request` and `session` proxies are LocalProxy objects reading the `request`/`session` attributes off the current AppContext in the `flask.app_ctx` ContextVar (src/flask/globals.py:57-62). If no context is set — or in Flask 3.x if an app context exists but was created without a request — dereferencing them raises this RuntimeError. It exists because request data is per-HTTP-request state that only makes sense while Flask is dispatching a request.
Source
Thrown at src/flask/globals.py:51
_no_app_msg = """\
Working outside of application context.
Attempted to use functionality that expected a current application to be set. To
solve this, set up an app context using 'with app.app_context()'. See the
documentation on app context for more information.\
"""
_cv_app: ContextVar[AppContext] = ContextVar("flask.app_ctx")
app_ctx: AppContextProxy = LocalProxy( # type: ignore[assignment]
_cv_app, unbound_message=_no_app_msg
)
current_app: FlaskProxy = LocalProxy( # type: ignore[assignment]
_cv_app, "app", unbound_message=_no_app_msg
)
g: _AppCtxGlobalsProxy = LocalProxy( # type: ignore[assignment]
_cv_app, "g", unbound_message=_no_app_msg
)
_no_req_msg = """\
Working outside of request context.
Attempted to use functionality that expected an active HTTP request. See the
documentation on request context for more information.\
"""
request: RequestProxy = LocalProxy( # type: ignore[assignment]
_cv_app, "request", unbound_message=_no_req_msg
)
session: SessionMixinProxy = LocalProxy( # type: ignore[assignment]
_cv_app, "session", unbound_message=_no_req_msg
)
def __getattr__(name: str) -> t.Any:
import warnings
if name == "request_ctx":
warnings.warn(View on GitHub ↗ (pinned to 6a2f545bfd)
Solutions
- Only access `request`/`session` inside view functions, before/after-request hooks, or template rendering during a request.
- In tests or scripts, wrap the code in `with app.test_request_context('/path'): ...` to simulate a request.
- For background work, extract the needed request data in the view and pass plain values to the task, or use `@copy_current_request_context` for threads.
- Move module-level `request` access into the function body so it evaluates during dispatch.
Example fix
# before
from flask import request
def get_locale():
return request.accept_languages.best # called from a script -> RuntimeError
# after
with app.test_request_context('/', headers={'Accept-Language': 'en'}):
locale = get_locale() Defensive patterns
Strategy: type-guard
Validate before calling
from flask import has_request_context, request
if has_request_context():
user_agent = request.headers.get("User-Agent")
else:
user_agent = None # or obtain the data from explicit parameters Type guard
from flask import has_request_context
def in_request() -> bool:
"""True if request/session proxies are usable."""
return has_request_context() Try / catch
try:
ip = request.remote_addr
except RuntimeError:
# Not inside an HTTP request (background thread, CLI, import time)
ip = None Prevention
- Only touch `request`/`session` inside view functions or code called from them; pass values (not the proxies) into helpers and threads.
- Guard logging formatters and shared utilities with `has_request_context()` (the pattern Flask's own docs use).
- In tests, wrap request-dependent code in `app.test_request_context('/path')`.
- Never read `request` at module import time or in `before_first_request`-style startup code.
When it happens
Trigger: Touching `flask.request` or `flask.session` outside request dispatch: at import time, inside `with app.app_context()` (app context alone has no request), in background threads/async tasks spawned from a view, in Celery tasks, or in a plain script. Also calling code paths that read `request` implicitly, e.g. `url_for` with `_external` relying on request host, or accessing `request.args` in a CLI command.
Common situations: Evaluating `request.args.get(...)` as a function default argument or at module level; background jobs trying to read the request that enqueued them; testing view helper functions directly instead of via `app.test_request_context()`; WebSocket/SSE handlers running after the request ended; confusing app context (which `flask shell` provides) with request context.
Related errors
- Working outside of application context. Attempted to use fu
- 'after_this_request' can only be used when a request context
- 'copy_current_request_context' can only be used when a reque
- There is no request in this context.
- 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/ea6e7aedc6ef3562.json.
Report an issue: GitHub ↗.