{"record":{"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/3596b1ab61cea85edb8970e83ff61daa073facf8/src/flask/ctx.py#L458-L494","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Always pop contexts in the reverse order you pushed them (LIFO).","Use nested 'with' blocks which guarantee correct LIFO teardown.","Do not pop an outer context while an inner one is still active."],"exampleFix":"# before\na.push(); b.push()\na.pop()  # b is active -> RuntimeError (expected b, got a)\nb.pop()\n\n# after\na.push(); b.push()\nb.pop()  # pop innermost first\na.pop()","handlingStrategy":"validation","validationCode":"from flask.globals import _cv_app\n\ndef is_active_context(ctx) -> bool:\n    return _cv_app.get(None) is ctx","typeGuard":"null","tryCatchPattern":"try:\n    ctx.pop()\nexcept RuntimeError as e:\n    if 'not the active context' in str(e):\n        # another context is on top; pop that first\n        pass\n    raise","preventionTips":["Always pop contexts in LIFO order.","Use nested 'with' blocks so teardown order is automatic."],"tags":["flask","context","lifecycle","resource-management"],"backgroundTag":null,"analyzedSha":"3596b1ab61cea85edb8970e83ff61daa073facf8","analyzedAt":"2026-08-11T20:11:52.622Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}