pallets/flask · error · RuntimeError

Cannot pop this context ({self!r}), it is not the active con

Error message

Cannot pop this context ({self!r}), it is not the active context ({ctx!r}).

What it means

Raised in `AppContext.pop()` (src/flask/ctx.py:476) when the context being popped is not the one currently stored in the `_cv_app` contextvar. Flask contexts form a stack managed via contextvars, and pops must occur in strict LIFO order; popping a context while a different one is active means push/pop calls were interleaved incorrectly, which would corrupt teardown ordering.

Source

Thrown at src/flask/ctx.py:476

        :param exc: An unhandled exception that was raised while the context was
            active. Passed to teardown functions.

        .. versionchanged:: 0.9
            Added the ``exc`` argument.
        """
        if self._cv_token is None:
            raise RuntimeError(f"Cannot pop this context ({self!r}), it is not pushed.")

        ctx = _cv_app.get(None)

        if ctx is None or self._cv_token is None:
            raise RuntimeError(
                f"Cannot pop this context ({self!r}), there is no active context."
            )

        if ctx is not self:
            raise RuntimeError(
                f"Cannot pop this context ({self!r}), it is not the active"
                f" context ({ctx!r})."
            )

        self._push_count -= 1

        if self._push_count > 0:
            return

        collect_errors = _CollectErrors()

        if self._request is not None:
            with collect_errors:
                self.app.do_teardown_request(self, exc)

            with collect_errors:
                self._request.close()

View on GitHub ↗ (pinned to 6a2f545bfd)

Solutions

  1. Ensure strict LIFO ordering: pop the most recently pushed context first, or better, use `with app.app_context():` / `with app.test_request_context():` blocks so ordering is automatic.
  2. Audit for a leaked context: find any `push()` on an error path without a matching `pop()` in a finally block.
  3. Never share a context object across threads or asyncio tasks — push and pop within the same execution flow.
  4. In tests, replace manual push/pop in setUp/tearDown with context-manager based fixtures (e.g. a pytest fixture that yields inside the `with` block).

Example fix

# before
ctx1 = app.app_context()
ctx1.push()
ctx2 = app.test_request_context("/")
ctx2.push()
ctx1.pop()  # RuntimeError: ctx2 is the active context

# after
with app.app_context():
    with app.test_request_context("/"):
        do_work()  # contexts popped in LIFO order automatically
Defensive patterns

Strategy: validation

Validate before calling

from flask import globals as flask_globals
# Only pop the context you pushed, in LIFO order:
ctx = app.app_context()
ctx.push()
try:
    ...
finally:
    ctx.pop()  # same object, guaranteed active

Try / catch

try:
    ctx.pop()
except AssertionError:
    # contexts popped out of order; log and re-raise — indicates a leaked push elsewhere
    raise

Prevention

When it happens

Trigger: Calling `ctx.pop()` on an app/request context that was pushed, then another context was pushed on top and not popped first. Typical API sequence: `ctx1 = app.app_context(); ctx1.push(); ctx2 = app2.app_context(); ctx2.push(); ctx1.pop()`. Also occurs when a `with app.app_context():` block exits after code inside pushed another context and leaked it, or when async/greenlet code pops a context in a different execution flow than the one that pushed it.

Common situations: Tests that manually push contexts in `setUp` and pop in `tearDown` while the test body pushes more contexts; pytest fixtures with mismatched push/pop; background threads or asyncio tasks sharing context objects across tasks; extensions or middleware that push a context and forget to pop it in an error path; nesting `test_request_context` inside `app_context` and exiting in the wrong order.

Related errors


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