{"id":"58ac894c4b43add3","repo":"pallets/flask","slug":"cannot-pop-this-context-self-r-it-is-not-the","errorCode":null,"errorMessage":"Cannot pop this context ({self!r}), it is not the active context ({ctx!r}).","messagePattern":"Cannot pop this context \\((.+?)\\), it is not the active context \\((.+?)\\)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/flask/ctx.py","lineNumber":476,"sourceCode":"\n        :param exc: An unhandled exception that was raised while the context was\n            active. Passed to teardown functions.\n\n        .. versionchanged:: 0.9\n            Added the ``exc`` argument.\n        \"\"\"\n        if self._cv_token is None:\n            raise RuntimeError(f\"Cannot pop this context ({self!r}), it is not pushed.\")\n\n        ctx = _cv_app.get(None)\n\n        if ctx is None or self._cv_token is None:\n            raise RuntimeError(\n                f\"Cannot pop this context ({self!r}), there is no active context.\"\n            )\n\n        if ctx is not self:\n            raise RuntimeError(\n                f\"Cannot pop this context ({self!r}), it is not the active\"\n                f\" context ({ctx!r}).\"\n            )\n\n        self._push_count -= 1\n\n        if self._push_count > 0:\n            return\n\n        collect_errors = _CollectErrors()\n\n        if self._request is not None:\n            with collect_errors:\n                self.app.do_teardown_request(self, exc)\n\n            with collect_errors:\n                self._request.close()\n","sourceCodeStart":458,"sourceCodeEnd":494,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/ctx.py#L458-L494","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"# before\nctx1 = app.app_context()\nctx1.push()\nctx2 = app.test_request_context(\"/\")\nctx2.push()\nctx1.pop()  # RuntimeError: ctx2 is the active context\n\n# after\nwith app.app_context():\n    with app.test_request_context(\"/\"):\n        do_work()  # contexts popped in LIFO order automatically","handlingStrategy":"validation","validationCode":"from flask import globals as flask_globals\n# Only pop the context you pushed, in LIFO order:\nctx = app.app_context()\nctx.push()\ntry:\n    ...\nfinally:\n    ctx.pop()  # same object, guaranteed active","typeGuard":null,"tryCatchPattern":"try:\n    ctx.pop()\nexcept AssertionError:\n    # contexts popped out of order; log and re-raise — indicates a leaked push elsewhere\n    raise","preventionTips":["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"],"tags":["flask","app-context","request-context","contextvars","lifecycle"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}