encode/httpx · error · RuntimeError
The request instance has not been set on this response.
Error message
The request instance has not been set on this response.
What it means
Raised by the `Response.request` property when `_request` is None. httpx links a Response to the Request that produced it at send time; if that link was never established, accessing `.request`, `.url`, or `.next_request` is undefined, so the property refuses to return a stale/empty value. This almost always means the Response was constructed by hand (tests, mocks, fixtures, or a custom transport) rather than returned by `client.request`/`client.get`.
Source
Thrown at httpx/_models.py:601
"""
if not hasattr(self, "_elapsed"):
raise RuntimeError(
"'.elapsed' may only be accessed after the response "
"has been read or closed."
)
return self._elapsed
@elapsed.setter
def elapsed(self, elapsed: datetime.timedelta) -> None:
self._elapsed = elapsed
@property
def request(self) -> Request:
"""
Returns the request instance associated to the current response.
"""
if self._request is None:
raise RuntimeError(
"The request instance has not been set on this response."
)
return self._request
@request.setter
def request(self, value: Request) -> None:
self._request = value
@property
def http_version(self) -> str:
try:
http_version: bytes = self.extensions["http_version"]
except KeyError:
return "HTTP/1.1"
else:
return http_version.decode("ascii", errors="ignore")
@propertyView on GitHub (pinned to b5addb64f0)
Solutions
- Pass a real request when constructing: `httpx.Response(200, request=httpx.Request('GET', url))`.
- In tests, use `httpx.MockTransport` or `respx` so httpx itself wires the request onto the Response.
- Guard before access: `if response._request is not None:` (private but stable) or restructure so you never need `.request` on synthetic responses.
- If you only need the URL, store it separately instead of relying on `response.url`, which delegates to `response.request.url`.
Example fix
// before
resp = httpx.Response(200, content=b'ok')
print(resp.url) # RuntimeError
// after
req = httpx.Request('GET', 'https://example.com/')
resp = httpx.Response(200, content=b'ok', request=req)
print(resp.url) Defensive patterns
Strategy: validation
Validate before calling
def safe_request(resp: httpx.Response) -> httpx.Request | None:
return getattr(resp, '_request', None) Type guard
import httpx
def has_request(resp: httpx.Response) -> bool:
return getattr(resp, '_request', None) is not None Try / catch
try:
req = response.request
except RuntimeError:
# synthetic response - synthesize a request or skip
req = None Prevention
- Always pass request= when constructing httpx.Response by hand.
- Prefer httpx.MockTransport / respx over hand-built Response objects in tests.
- Custom transports must set response.request = request before returning.
When it happens
Trigger: Calling `httpx.Response(200, content=b'...').request`, `response.url`, or any code path that reads `self.request` on a Response built via the `httpx.Response(...)` constructor without a `request=` argument. Also triggered by `raise_for_status()` on such a Response (see error 43) and by `extract_cookies` flows that dereference `response.request`.
Common situations: Unit tests that build a fake `httpx.Response` for a mock transport but forget to pass `request=httpx.Request('GET', 'https://example.com')`; custom `httpx.BaseTransport`/`AsyncBaseTransport` implementations that return a hand-built Response; upgrading from `requests` where manually building Response-like objects was common.
Related errors
- Cannot call `raise_for_status` as the request instance has n
- '.elapsed' may only be accessed after the response has been
- Attempted to access streaming response content, without havi
- Attempted to read or stream some content, but the content ha
- Attempted to read or stream content, but the stream has been
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/4d51d6c38b2a016b.json.
Report an issue: GitHub.