psf/requests · error · RuntimeError
The content for this response was already consumed
Error message
The content for this response was already consumed
What it means
Raised by the Response.content property when the underlying stream has already been consumed (e.g. via iter_content with stream=True) but _content was never populated. This is a RuntimeError, not the more specific StreamConsumedError (which is raised from iter_content itself). It signals an irreversible state: the socket data was read and discarded, so .content cannot materialize the bytes retroactively.
Solutions
- Decide on ONE access pattern: either use stream=False and read .content, or use stream=True and fully consume iter_content() — never both.
- If you already streamed and need the bytes, collect them during iteration: data = b''.join(resp.iter_content(8192)).
- Buffer the stream into a variable early if you need to re-read: raw = resp.content before any streaming call.
Example fix
# before (stream=True)
for chunk in resp.iter_content(8192):
process(chunk)
body = resp.content # RuntimeError
# after — collect during iteration
body = b''.join(resp.iter_content(8192)) Defensive patterns
Strategy: validation
Validate before calling
if resp._content_consumed and isinstance(resp._content, bool):
raise RuntimeError('Content already consumed via streaming')
body = resp.content Try / catch
try:
body = resp.content
except RuntimeError:
# Stream was consumed; re-fetch or use buffered data
body = cached_stream_data Prevention
- Never mix iter_content/iter_lines with .content on the same Response.
- When using stream=True, collect all bytes during iteration: body = b''.join(resp.iter_content(8192)).
- Document which functions consume a response's stream to prevent accidental double-reads.
When it happens
Trigger: Calling resp.iter_content() on a streaming response (stream=True) and then accessing resp.content afterwards; iterating over resp.iter_lines() and then calling resp.content; calling resp.content after resp.content on a streaming response whose _content is still False but _content_consumed was set True by a prior generator iteration.
Common situations: Mixing streaming and non-streaming access patterns on the same Response object; a helper function that calls iter_content() internally followed by code that reads .content; refactoring from stream=False to stream=True without updating downstream .content access.
Related errors
AI-assisted analysis of psf/requests@8068356288 (2026-08-11).
Data as JSON: /api/errors/d7997d5baf4be9bb.
Report an issue: GitHub.
Appendix: source
Thrown at src/requests/models.py:1041
if lines and lines[-1] and chunk and lines[-1][-1] == chunk[-1]:
pending = lines.pop()
else:
pending = None
yield from lines
if pending is not None:
yield pending
@property
def content(self) -> bytes:
"""Content of the response, in bytes."""
if self._content is False:
# Read the contents.
if self._content_consumed:
raise RuntimeError("The content for this response was already consumed")
if self.status_code == 0 or self.raw is None:
self._content = None
else:
self._content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) or b""
self._content_consumed = True
# don't need to release the connection; that's been handled by urllib3
# since we exhausted the data.
return self._content # type: ignore[return-value]
@property
def text(self) -> str:
"""Content of the response, in unicode.
If Response.encoding is None, encoding will be guessed using
``charset_normalizer`` or ``chardet``.
View on GitHub (pinned to 8068356288)