pallets/flask · error · RuntimeError

Cannot pop this context

Error message

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

What it means

In pop(), the active context read from _cv_app.get(None) is a different object than self. Flask raises RuntimeError naming both the context you tried to pop and the one that is actually active. This catches out-of-order pops: contexts are a stack, and you must pop in LIFO order.

Solutions

  1. Always pop contexts in the reverse order you pushed them (LIFO).
  2. Use nested 'with' blocks which guarantee correct LIFO teardown.
  3. Do not pop an outer context while an inner one is still active.

Example fix

# before
a.push(); b.push()
a.pop()  # b is active -> RuntimeError (expected b, got a)
b.pop()

# after
a.push(); b.push()
b.pop()  # pop innermost first
a.pop()
Defensive patterns

Strategy: validation

Validate before calling

from flask.globals import _cv_app

def is_active_context(ctx) -> bool:
    return _cv_app.get(None) is ctx

Type guard

null

Try / catch

try:
    ctx.pop()
except RuntimeError as e:
    if 'not the active context' in str(e):
        # another context is on top; pop that first
        pass
    raise

Prevention

When it happens

Trigger: Pushing context A then context B, then calling A.pop() while B is still active. Or popping a context after a newer one was pushed and not yet popped. The active (top-of-stack) context must equal self for pop() to proceed.

Common situations: Manual nested context management where pops are reordered. A finally block popping the outer context before the inner one. Background tasks holding an old context reference while a newer one is active.

Related errors


AI-assisted analysis of pallets/flask@3596b1ab61 (2026-08-11). Data as JSON: /api/errors/58ac894c4b43add3. Report an issue: GitHub.

Appendix: 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 3596b1ab61)