{"id":"d7997d5baf4be9bb","repo":"psf/requests","slug":"the-content-for-this-response-was-already-consumed","errorCode":null,"errorMessage":"The content for this response was already consumed","messagePattern":"The content for this response was already consumed","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/requests/models.py","lineNumber":1041,"sourceCode":"\n            if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:\n                pending = lines.pop()\n            else:\n                pending = None\n\n            yield from lines\n\n        if pending is not None:\n            yield pending\n\n    @property\n    def content(self) -> bytes:\n        \"\"\"Content of the response, in bytes.\"\"\"\n\n        if self._content is False:\n            # Read the contents.\n            if self._content_consumed:\n                raise RuntimeError(\"The content for this response was already consumed\")\n\n            if self.status_code == 0 or self.raw is None:\n                self._content = None\n            else:\n                self._content = b\"\".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b\"\"\n\n        self._content_consumed = True\n        # don't need to release the connection; that's been handled by urllib3\n        # since we exhausted the data.\n        return self._content  # type: ignore[return-value]\n\n    @property\n    def text(self) -> str:\n        \"\"\"Content of the response, in unicode.\n\n        If Response.encoding is None, encoding will be guessed using\n        ``charset_normalizer`` or ``chardet``.\n","sourceCodeStart":1023,"sourceCodeEnd":1059,"githubUrl":"https://github.com/psf/requests/blob/414f0513c33883adf6f2b46901d4f0b38a455851/src/requests/models.py#L1023-L1059","documentation":"A `RuntimeError` raised by the `Response.content` property when the response body was already consumed from the underlying stream (`_content_consumed` is True) but never cached into `_content` (still False). This happens only for streamed responses: once you iterate the raw stream, the bytes are gone from the socket, so a later `.content`/`.text`/`.json()` access cannot recover them.","triggerScenarios":"With `requests.get(url, stream=True)`: first drain the body via `iter_content()`/`iter_lines()` (or `raw.read`), then access `resp.content`, `resp.text`, or `resp.json()`. Accessing `.content` first and iterating later does NOT raise — caching only fails in the stream-then-access order.","commonSituations":"Logging middleware or debugging code that calls `resp.text` after the application already streamed the body to disk; retry/error handlers that try to read `resp.json()` from a response that was partially streamed; sharing a streamed Response object between two consumers.","solutions":["Access `resp.content` (or `.text`/`.json()`) FIRST — it caches the whole body, and subsequent `iter_content` calls replay from the cache.","If you need both streaming and later access, tee the chunks yourself: collect them into a buffer while streaming and reuse that buffer.","If streaming isn't actually needed, drop `stream=True` so the body is read and cached eagerly.","Don't reuse a drained streamed Response across consumers — re-request or pass the saved bytes instead."],"exampleFix":"# before\nresp = requests.get(url, stream=True)\nfor chunk in resp.iter_content(8192):\n    f.write(chunk)\nlog.debug(resp.text)  # RuntimeError\n\n# after\nresp = requests.get(url, stream=True)\nbuf = bytearray()\nfor chunk in resp.iter_content(8192):\n    f.write(chunk)\n    buf.extend(chunk)\nlog.debug(buf.decode(resp.encoding or 'utf-8'))","handlingStrategy":"try-catch","validationCode":"# safe to touch .content only if already consumed or stream still open\ncan_read = resp._content is not False or not resp.raw.closed  # or simply: access resp.content once and reuse it","typeGuard":null,"tryCatchPattern":"try:\n    body = resp.content\nexcept RuntimeError:\n    # stream was partially read via iter_content/raw then closed\n    ...  # re-issue the request; the body is unrecoverable","preventionTips":["With stream=True, consume the body exactly once — either iterate iter_content OR read .content/.text, never both","Access resp.content once and cache it in a variable instead of re-reading the stream","Don't call resp.close() (or exit a `with` block) before you've read the body","If mixing is unavoidable, call resp.content first — it caches, and later .text/.json() reuse the cache"],"tags":["python","requests","streaming","response-body","stream-consumed"],"analyzedSha":"414f0513c33883adf6f2b46901d4f0b38a455851","analyzedAt":"2026-07-31T19:24:57.696Z","schemaVersion":2}