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

  1. Only access `request`/`session` inside view functions, before/after-request hooks, or template rendering during a request.
  2. In tests or scripts, wrap the code in `with app.test_request_context('/path'): ...` to simulate a request.
  3. 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.
  4. 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

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


AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31). Data as JSON: /data/errors/ea6e7aedc6ef3562.json. Report an issue: GitHub ↗.