{"id":"04dc5e96abc5dfa1","repo":"encode/httpx","slug":"attempted-to-call-an-async-iterator-on-a-sync-stre","errorCode":null,"errorMessage":"Attempted to call an async iterator on a sync stream.","messagePattern":"Attempted to call an async iterator on a sync stream\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"httpx/_models.py","lineNumber":1048,"sourceCode":"        with request_context(request=self._request):\n            async for text in self.aiter_text():\n                for line in decoder.decode(text):\n                    yield line\n            for line in decoder.flush():\n                yield line\n\n    async def aiter_raw(\n        self, chunk_size: int | None = None\n    ) -> typing.AsyncIterator[bytes]:\n        \"\"\"\n        A byte-iterator over the raw response content.\n        \"\"\"\n        if self.is_stream_consumed:\n            raise StreamConsumed()\n        if self.is_closed:\n            raise StreamClosed()\n        if not isinstance(self.stream, AsyncByteStream):\n            raise RuntimeError(\"Attempted to call an async iterator on a sync stream.\")\n\n        self.is_stream_consumed = True\n        self._num_bytes_downloaded = 0\n        chunker = ByteChunker(chunk_size=chunk_size)\n\n        with request_context(request=self._request):\n            async for raw_stream_bytes in self.stream:\n                self._num_bytes_downloaded += len(raw_stream_bytes)\n                for chunk in chunker.decode(raw_stream_bytes):\n                    yield chunk\n\n        for chunk in chunker.flush():\n            yield chunk\n\n        await self.aclose()\n\n    async def aclose(self) -> None:\n        \"\"\"","sourceCodeStart":1030,"sourceCodeEnd":1066,"githubUrl":"https://github.com/encode/httpx/blob/b5addb64f0161ff6bfe94c124ef76f6a1fba5254/httpx/_models.py#L1030-L1066","documentation":"Raised as `RuntimeError` by async `aiter_raw()` when `self.stream` is not an `AsyncByteStream`. The Response came from a sync `httpx.Client` but you used an async iteration method. httpx refuses to silently run a sync iterator inside an async context.","triggerScenarios":"Calling `async for chunk in response.aiter_bytes():` or `await response.aread()` on a Response returned by sync `httpx.Client.get()`.","commonSituations":"Accidentally wrapping sync client calls in an async function; shared helpers originally written for async that get reused with a sync client; framework code that assumes async responses everywhere.","solutions":["Use sync iteration (`for chunk in response.iter_bytes()`, `response.read()`) for sync-client responses.","Pick one concurrency model per code path and stick to it.","If async is required, switch the client to `httpx.AsyncClient`.","Type-annotate helpers so mypy/pyright flags the mismatch."],"exampleFix":"// before\nasync def handler():\n    r = sync_client.get(url)\n    async for c in r.aiter_bytes():  # RuntimeError\n        ...\n\n// after\nasync def handler():\n    async with httpx.AsyncClient() as c:\n        r = await c.get(url)\n        async for c in r.aiter_bytes():\n            ...","handlingStrategy":"type-guard","validationCode":"from httpx._transports.default import SyncByteStream\n\ndef is_sync_response(resp: httpx.Response) -> bool:\n    return isinstance(resp.stream, SyncByteStream)","typeGuard":"import httpx\nfrom httpx._transports.default import SyncByteStream\n\ndef is_sync_stream(resp: httpx.Response) -> bool:\n    return isinstance(resp.stream, SyncByteStream)","tryCatchPattern":"try:\n    async for chunk in response.aiter_bytes():\n        ...\nexcept RuntimeError:\n    # sync stream - use sync iteration\n    for chunk in response.iter_bytes():\n        ...","preventionTips":["Only call async methods on responses from AsyncClient.","Keep sync and async code paths strictly separated.","If async is required, migrate the client to AsyncClient."],"tags":["sync-async","streaming","asyncio","runtime-error"],"analyzedSha":"b5addb64f0161ff6bfe94c124ef76f6a1fba5254","analyzedAt":"2026-08-04T19:32:56.768Z","schemaVersion":2}