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
- 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.
- Audit for a leaked context: find any `push()` on an error path without a matching `pop()` in a finally block.
- Never share a context object across threads or asyncio tasks — push and pop within the same execution flow.
- 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
- Prefer `with app.app_context():` / `with app.test_request_context():` so push/pop pairing is automatic
- Never store a context and pop it from a different thread or coroutine
- Always pop in strict LIFO order; use try/finally around every manual push
- Avoid manual push/pop entirely in tests — use the test client context managers
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
- Cannot pop this context ({self!r}), there is no active conte
- Working outside of application context. Attempted to use fu
- Working outside of request context. Attempted to use functi
- 'after_this_request' can only be used when a request context
- 'copy_current_request_context' can only be used when a reque
AI-assisted analysis of pallets/flask@6a2f545bfd (2026-07-31).
Data as JSON: /data/errors/58ac894c4b43add3.json.
Report an issue: GitHub ↗.