pallets/flask · error · RuntimeError

'stream_with_context' can only be used when a request contex

Error message

'stream_with_context' can only be used when a request context is active, such as in a view function.

What it means

stream_with_context keeps the current request context alive while a streaming response generator runs. It captures the active context from the _cv_app context variable at first iteration; if no request context is active there is nothing to preserve, so the wrapped generator raises RuntimeError when consumed.

Source

Thrown at src/flask/helpers.py:128

                yield "!"

            return Response(stream_with_context(generate()))

    .. versionadded:: 0.9
    """
    try:
        gen = iter(generator_or_function)  # type: ignore[arg-type]
    except TypeError:

        def decorator(*args: t.Any, **kwargs: t.Any) -> t.Any:
            gen = generator_or_function(*args, **kwargs)  # type: ignore[operator]
            return stream_with_context(gen)

        return update_wrapper(decorator, generator_or_function)  # type: ignore[arg-type]

    def generator() -> t.Iterator[t.AnyStr]:
        if (ctx := _cv_app.get(None)) is None:
            raise RuntimeError(
                "'stream_with_context' can only be used when a request"
                " context is active, such as in a view function."
            )

        with ctx:
            yield None  # type: ignore[misc]

            try:
                yield from gen
            finally:
                # Clean up in case the user wrapped a WSGI iterator.
                if hasattr(gen, "close"):
                    gen.close()

    # Execute the generator to the sentinel value. This captures the current
    # context and pushes it to preserve it. Further iteration will yield from
    # the original iterator.
    wrapped_g = generator()

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Only create and return stream_with_context generators from inside a view function, wrapped in Response(stream_with_context(gen())).
  2. In tests, wrap consumption in app.test_request_context(): with app.test_request_context('/'): ...
  3. If no request data is actually needed, drop stream_with_context and pass the plain generator to Response.
  4. For background work, copy the needed request values into local variables before spawning the worker instead of streaming the context.

Example fix

# before
gen = stream_with_context(generate())
next(gen)  # outside any request
# after
@app.route('/stream')
def stream():
    return Response(stream_with_context(generate()))
Defensive patterns

Strategy: type-guard

Validate before calling

from flask import has_request_context
if not has_request_context():
    raise RuntimeError("stream_with_context must be called inside a view/request; restructure the code")

Type guard

from flask import has_request_context
def can_stream_with_context() -> bool:
    return has_request_context()

Try / catch

try:
    return Response(stream_with_context(generate()))
except RuntimeError:
    # called outside a request (e.g. CLI/背景 job) — capture needed values eagerly instead
    raise

Prevention

When it happens

Trigger: Iterating a stream_with_context(...) generator outside a request — e.g. constructing it in a background thread, a CLI command, app startup code, or a test without test_request_context(); also wrapping a generator in a view but consuming it after the context was torn down without Flask's Response driving it.

Common situations: Moving streaming code into Celery/thread workers; unit tests calling the view function directly instead of via test_client; calling next() on the generator eagerly before returning the Response.

Related errors


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