{"id":"e0c6993e2caabbcc","repo":"encode/httpx","slug":"cannot-send-a-request-as-the-client-has-been-clos","errorCode":null,"errorMessage":"Cannot send a request, as the client has been closed.","messagePattern":"Cannot send a request, as the client has been closed\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"httpx/_client.py","lineNumber":901,"sourceCode":"        stream: bool = False,\n        auth: AuthTypes | UseClientDefault | None = USE_CLIENT_DEFAULT,\n        follow_redirects: bool | UseClientDefault = USE_CLIENT_DEFAULT,\n    ) -> Response:\n        \"\"\"\n        Send a request.\n\n        The request is sent as-is, unmodified.\n\n        Typically you'll want to build one with `Client.build_request()`\n        so that any client-level configuration is merged into the request,\n        but passing an explicit `httpx.Request()` is supported as well.\n\n        See also: [Request instances][0]\n\n        [0]: /advanced/clients/#request-instances\n        \"\"\"\n        if self._state == ClientState.CLOSED:\n            raise RuntimeError(\"Cannot send a request, as the client has been closed.\")\n\n        self._state = ClientState.OPENED\n        follow_redirects = (\n            self.follow_redirects\n            if isinstance(follow_redirects, UseClientDefault)\n            else follow_redirects\n        )\n\n        self._set_timeout(request)\n\n        auth = self._build_request_auth(request, auth)\n\n        response = self._send_handling_auth(\n            request,\n            auth=auth,\n            follow_redirects=follow_redirects,\n            history=[],\n        )","sourceCodeStart":883,"sourceCodeEnd":919,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_client.py#L883-L919","documentation":"Raised as RuntimeError by the sync Client.send() path when self._state == ClientState.CLOSED. Once close()/__exit__ has run the client refuses any further requests.","triggerScenarios":"Calling client.get/send/client.stream after client.close(), or after the 'with client:' block has exited (which sets state to CLOSED).","commonSituations":"Reusing a client stored globally after it was closed; issuing requests outside the with-block; a shared client closed by one consumer while another still uses it.","solutions":["Perform all requests inside a single 'with httpx.Client() as client:' block.","If the client was closed, construct a fresh httpx.Client instead of reusing it.","Avoid calling client.close() (or exiting its context) before outstanding requests finish."],"exampleFix":"// before\nwith httpx.Client() as c:\n    pass\nc.get(url)  # RuntimeError: closed\n// after\nwith httpx.Client() as c:\n    c.get(url)","handlingStrategy":"validation","validationCode":"import httpx\ndef ensure_open(client: httpx.Client) -> None:\n    if client.is_closed:\n        raise RuntimeError(\"client is closed; create a new httpx.Client\")\n\nensure_open(client)\nclient.get(url)","typeGuard":"import httpx\n\ndef is_usable(client: httpx.Client) -> bool:\n    return not client.is_closed","tryCatchPattern":"try:\n    client.get(url)\nexcept RuntimeError as exc:\n    if \"has been closed\" in str(exc):\n        client = httpx.Client(...)  # recreate\n        client.get(url)\n    else:\n        raise","preventionTips":["Keep all requests inside the client's 'with' block.","Check client.is_closed before reusing a stored client.","Never share a client with code that may close it concurrently."],"tags":["lifecycle","client","sync"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}