encode/httpx · error · RuntimeError
Attempted to call an async close on a sync stream.
Error message
Attempted to call an async close on a sync stream.
What it means
Raised as `RuntimeError` by async `aclose()` when `self.stream` is not an `AsyncByteStream`. You awaited the async close on a Response whose underlying stream is sync (came from `httpx.Client`).
Source
Thrown at httpx/_models.py:1071
with request_context(request=self._request):
async for raw_stream_bytes in self.stream:
self._num_bytes_downloaded += len(raw_stream_bytes)
for chunk in chunker.decode(raw_stream_bytes):
yield chunk
for chunk in chunker.flush():
yield chunk
await self.aclose()
async def aclose(self) -> None:
"""
Close the response and release the connection.
Automatically called if the response body is read to completion.
"""
if not isinstance(self.stream, AsyncByteStream):
raise RuntimeError("Attempted to call an async close on a sync stream.")
if not self.is_closed:
self.is_closed = True
with request_context(request=self._request):
await self.stream.aclose()
class Cookies(typing.MutableMapping[str, str]):
"""
HTTP Cookies, as a mutable mapping.
"""
def __init__(self, cookies: CookieTypes | None = None) -> None:
if cookies is None or isinstance(cookies, dict):
self.jar = CookieJar()
if isinstance(cookies, dict):
for key, value in cookies.items():
self.set(key, value)View on GitHub (pinned to b5addb64f0)
Solutions
- Use `response.close()` for sync-client responses.
- Keep cleanup logic paired with the matching client type.
- Switch to `httpx.AsyncClient` if the surrounding code is async.
- Branch the cleanup: `if isinstance(resp.stream, httpx._transports.default.AsyncByteStream): await resp.aclose() else: resp.close()`.
Example fix
// before r = sync_client.get(url) await r.aclose() # RuntimeError // after r = sync_client.get(url) r.close()
Defensive patterns
Strategy: type-guard
Validate before calling
from httpx._transports.default import SyncByteStream
def needs_close(resp: httpx.Response) -> bool:
return isinstance(resp.stream, SyncByteStream) Type guard
import httpx
from httpx._transports.default import SyncByteStream
def is_sync_stream(resp: httpx.Response) -> bool:
return isinstance(resp.stream, SyncByteStream) Try / catch
try:
await response.aclose()
except RuntimeError:
response.close() Prevention
- close() sync responses; aclose() async responses.
- Keep cleanup paired with the originating client type.
- Migrate to AsyncClient if the surrounding code is async.
When it happens
Trigger: Calling `await response.aclose()` on a Response produced by sync `httpx.Client`.
Common situations: Generic async cleanup helpers that always `await resp.aclose()`; mixing a sync client into an async service; partial migration leaving sync clients behind.
Related errors
- Attempted to call a sync close on an async stream.
- Attempted to call a sync iterator on an async stream.
- Attempted to call an async iterator on a sync stream.
- Attempted to send an async request with a sync Client instan
- Attempted to send a sync request with an AsyncClient instanc
AI-assisted analysis of encode/httpx@b5addb64f0 (2026-08-04).
Data as JSON: /data/errors/7f613e413ffa741d.json.
Report an issue: GitHub.