{"id":"b4284d5c9ea61cb4","repo":"pallets/flask","slug":"cannot-nest-client-invocations","errorCode":null,"errorMessage":"Cannot nest client invocations","messagePattern":"Cannot nest client invocations","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/flask/testing.py","lineNumber":251,"sourceCode":"        self._context_stack.close()\n\n        response = super().open(\n            request,\n            buffered=buffered,\n            follow_redirects=follow_redirects,\n        )\n        response.json_module = self.application.json  # type: ignore[assignment]\n\n        # Re-push contexts that were preserved during the request.\n        for cm in self._new_contexts:\n            self._context_stack.enter_context(cm)\n\n        self._new_contexts.clear()\n        return response\n\n    def __enter__(self) -> FlaskClient:\n        if self.preserve_context:\n            raise RuntimeError(\"Cannot nest client invocations\")\n        self.preserve_context = True\n        return self\n\n    def __exit__(\n        self,\n        exc_type: type | None,\n        exc_value: BaseException | None,\n        tb: TracebackType | None,\n    ) -> None:\n        self.preserve_context = False\n        self._context_stack.close()\n\n\nclass FlaskCliRunner(CliRunner):\n    \"\"\"A :class:`~click.testing.CliRunner` for testing a Flask app's\n    CLI commands. Typically created using\n    :meth:`~flask.Flask.test_cli_runner`. See :ref:`testing-cli`.\n    \"\"\"","sourceCodeStart":233,"sourceCodeEnd":269,"githubUrl":"https://github.com/pallets/flask/blob/6a2f545bfd8ed31e19066a299296917e034aca58/src/flask/testing.py#L233-L269","documentation":"Raised as a RuntimeError by `FlaskClient.__enter__` when `preserve_context` is already True, i.e. you entered the same test client as a context manager while it is already inside a `with` block. The `with client:` form preserves request contexts after each request so you can inspect `request`/`session`; nesting would corrupt the preserved-context stack, so Flask forbids it.","triggerScenarios":"`with client:` inside another `with client:` on the same FlaskClient instance; re-entering a client that was never exited (e.g. an exception path skipped `__exit__`, or a fixture yields an already-entered client and a test enters it again).","commonSituations":"Pytest fixtures that do `with app.test_client() as client: yield client` combined with tests that also write `with client:`; helper functions that wrap requests in `with self.client:` and get called from within another such block.","solutions":["Remove the inner `with client:` — use the already-entered client directly.","Enter the client in exactly one place (either the fixture or the test, not both).","If you genuinely need parallel independent request contexts, create a second client with `app.test_client()`."],"exampleFix":"# before\nwith client:\n    with client:  # RuntimeError\n        client.get(\"/\")\n# after\nwith client:\n    client.get(\"/\")\n    assert request.path == \"/\"","handlingStrategy":"validation","validationCode":"# don't call the client inside a route/before-request handler triggered by the same client\n# perform sequential requests instead:\nr1 = client.get('/a')\nr2 = client.get('/b')  # after r1 completes","typeGuard":null,"tryCatchPattern":"try:\n    resp = client.get('/endpoint')\nexcept RuntimeError as e:\n    if 'Cannot nest client invocations' in str(e):\n        # a request handler is re-invoking the same test client\n        raise","preventionTips":["Never call the test client from code executed during one of its own requests (routes, signals, before/after hooks)","Make requests sequentially; don't share one client across nested contexts","If a handler must call another endpoint in tests, refactor to call the view function or service layer directly"],"tags":["flask","testing","context-manager","request-context"],"analyzedSha":"6a2f545bfd8ed31e19066a299296917e034aca58","analyzedAt":"2026-07-31T19:13:49.921Z","schemaVersion":2}