aio-libs/aiohttp · error · RuntimeError
Cannot compute fallback encoding of a not yet read body
Error message
Cannot compute fallback encoding of a not yet read body
What it means
Raised by ClientResponse.get_encoding() when no charset can be determined from the Content-Type header or mimetype defaults, and the response body has not been read yet. get_encoding() falls back to charset detection on self._body, but if _body is None (unread) it cannot run the detector and raises RuntimeError. This typically means get_encoding()/text()/json() was called before read() in a streaming context.
Solutions
- Call await resp.read() before resp.get_encoding() so _body is populated.
- Prefer resp.text() / resp.json() which call read() internally.
- If you control the server, send an explicit charset: 'Content-Type: text/html; charset=utf-8'.
- Pass encoding explicitly to text(encoding='utf-8') to bypass detection.
Example fix
# before enc = resp.get_encoding() # _body is None -> RuntimeError body = await resp.read() # after body = await resp.read() enc = resp.get_encoding() # now _body is available for fallback detection
Defensive patterns
Strategy: validation
Validate before calling
async def safe_get_encoding(resp) -> str:
if resp._body is None:
await resp.read() # populate body before detection
return resp.get_encoding() Type guard
def body_is_read(resp) -> bool:
return getattr(resp, '_body', None) is not None Try / catch
try:
enc = resp.get_encoding()
except RuntimeError as e:
if 'not yet read body' in str(e):
await resp.read()
enc = resp.get_encoding()
else:
raise Prevention
- Always call await resp.read() before get_encoding().
- Prefer resp.text() which handles encoding internally.
- Send explicit charset headers from your server to avoid detection.
When it happens
Trigger: Calling resp.get_encoding() (or resp.text()/resp.json() in a path where read() hasn't populated _body) on a response whose Content-Type has no charset and is not JSON/RDAP, while _body is still None. text()/json() normally call read() first, so this most often arises from calling get_encoding() directly or from a custom code path.
Common situations: Calling get_encoding() manually before reading the body; a response with 'Content-Type: text/html' (no charset) where the app tries to detect encoding prematurely; subclassing ClientResponse and invoking encoding logic out of order.
Related errors
- Connection closed
- Attempt to decode JSON with unexpected mimetype
- data argument must be str (%r)
- InvalidURL
- 1002
AI-assisted analysis of aio-libs/aiohttp@d041d4d0fd (2026-08-11).
Data as JSON: /api/errors/efe0c08e8859dd4a.
Report an issue: GitHub.
Appendix: source
Thrown at aiohttp/client_reqrep.py:730
def get_encoding(self) -> str:
ctype = self.headers.get(hdrs.CONTENT_TYPE, "").lower()
mimetype = parse_mimetype(ctype)
encoding = mimetype.parameters.get("charset")
if encoding:
with contextlib.suppress(LookupError, ValueError):
return codecs.lookup(encoding).name
if mimetype.type == "application" and (
mimetype.subtype == "json" or mimetype.subtype == "rdap"
):
# RFC 7159 states that the default encoding is UTF-8.
# RFC 7483 defines application/rdap+json
return "utf-8"
if self._body is None:
raise RuntimeError(
"Cannot compute fallback encoding of a not yet read body"
)
return self._resolve_charset(self, self._body)
async def text(self, encoding: str | None = None, errors: str = "strict") -> str:
"""Read response payload and decode."""
await self.read()
if encoding is None:
encoding = self.get_encoding()
return self._body.decode(encoding, errors=errors) # type: ignore[union-attr]
async def json(
self,
*,
encoding: str | None = None,View on GitHub (pinned to d041d4d0fd)