{"id":"18ce8ab2b718d4b1","repo":"encode/httpx","slug":"attempted-to-access-streaming-response-content-wi","errorCode":null,"errorMessage":"Attempted to access streaming response content, without having called `read()`.","messagePattern":"Attempted to access streaming response content, without having called `read\\(\\)`\\.","errorType":"exception","errorClass":"ResponseNotRead","httpStatus":null,"severity":"error","filePath":"httpx/_models.py","lineNumber":638,"sourceCode":"    def reason_phrase(self) -> str:\n        try:\n            reason_phrase: bytes = self.extensions[\"reason_phrase\"]\n        except KeyError:\n            return codes.get_reason_phrase(self.status_code)\n        else:\n            return reason_phrase.decode(\"ascii\", errors=\"ignore\")\n\n    @property\n    def url(self) -> URL:\n        \"\"\"\n        Returns the URL for which the request was made.\n        \"\"\"\n        return self.request.url\n\n    @property\n    def content(self) -> bytes:\n        if not hasattr(self, \"_content\"):\n            raise ResponseNotRead()\n        return self._content\n\n    @property\n    def text(self) -> str:\n        if not hasattr(self, \"_text\"):\n            content = self.content\n            if not content:\n                self._text = \"\"\n            else:\n                decoder = TextDecoder(encoding=self.encoding or \"utf-8\")\n                self._text = \"\".join([decoder.decode(self.content), decoder.flush()])\n        return self._text\n\n    @property\n    def encoding(self) -> str | None:\n        \"\"\"\n        Return an encoding to use for decoding the byte content into text.\n        The priority for determining this is given by...","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L620-L656","documentation":"Raised as `ResponseNotRead` (a `StreamError` subclass) by the `Response.content` property when no `_content` attribute exists yet. For a streaming response (one whose body has not been buffered), httpx will not implicitly read the network; you must call `.read()` (sync) or `.aread()` (async) first. Accessing `.content`, `.text`, or `.json()` before that triggers this error.","triggerScenarios":"Calling `client.stream('GET', url)` (or `client.send(req, stream=True)`), then inside or after the context reading `response.text`/`response.content`/`response.json()` without first awaiting/calling `response.aread()`/`response.read()`. Also reproducible by manually building `httpx.Response(200, stream=...)` and touching `.content`.","commonSituations":"Migrating from `requests` where `r.text` lazily read the body; forgetting that `with client.stream(...)` does NOT auto-read the body; mixing sync `.read()` with an async client.","solutions":["Inside a streaming context, call `response.read()` (sync) or `await response.aread()` (async) before accessing `.content`/`.text`/`.json()`.","If you always want the full body, drop `stream=True` / `client.stream(...)` and use plain `client.get(...)` which reads automatically.","For an already-closed stream, re-issue the request rather than retrying `.read()`.","Use `iter_raw`/`iter_bytes`/`aiter_bytes` if you want to consume the body incrementally instead of buffering."],"exampleFix":"// before\nwith client.stream('GET', url) as r:\n    pass\nprint(r.text)  # ResponseNotRead\n\n// after\nwith client.stream('GET', url) as r:\n    r.read()\nprint(r.text)","handlingStrategy":"validation","validationCode":"def is_read(resp: httpx.Response) -> bool:\n    return hasattr(resp, '_content')","typeGuard":"import httpx\n\ndef response_is_buffered(resp: httpx.Response) -> bool:\n    return hasattr(resp, '_content')","tryCatchPattern":"try:\n    body = response.content\nexcept httpx.ResponseNotRead:\n    await response.aread()  # or response.read() for sync\n    body = response.content","preventionTips":["Call read()/aread() inside every streaming context before touching the body.","Use non-streaming client.get() when you always want the full body.","Centralize body access in one helper so the read step is never skipped."],"tags":["streaming","response","response-not-read","runtime-error"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}