{"record":{"id":"9f15af9f9911ca83","repo":"PrefectHQ/fastmcp","slug":"streamingasgitransport-requires-an-async-request-s","errorCode":null,"errorMessage":"StreamingASGITransport requires an async request stream; got {type(request.stream).__name__}.","messagePattern":"StreamingASGITransport requires an async request stream; got (.+?)\\.","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"fastmcp_slim/fastmcp/utilities/asgi_transport.py","lineNumber":130,"sourceCode":"        await self._task_group.__aenter__()\n        return self\n\n    async def __aexit__(\n        self,\n        exc_type: type[BaseException] | None = None,\n        exc_value: BaseException | None = None,\n        traceback: TracebackType | None = None,\n    ) -> None:\n        # httpx closes every streamed response before closing the transport, so by now each\n        # application task has been delivered `http.disconnect`. Either cancel immediately,\n        # or wait for the application's own disconnect handling to unwind.\n        if self._cancel_on_close:\n            self._task_group.cancel_scope.cancel()\n        await self._task_group.__aexit__(exc_type, exc_value, traceback)\n\n    async def handle_async_request(self, request: httpx2.Request) -> httpx2.Response:\n        if not isinstance(request.stream, httpx2.AsyncByteStream):\n            raise TypeError(\n                \"StreamingASGITransport requires an async request stream; \"\n                f\"got {type(request.stream).__name__}.\"\n            )\n        request_body = b\"\".join([chunk async for chunk in request.stream])\n\n        scope: Scope = {\n            \"type\": \"http\",\n            \"asgi\": {\"version\": \"3.0\"},\n            \"http_version\": \"1.1\",\n            \"method\": request.method,\n            \"scheme\": request.url.scheme,\n            \"path\": request.url.path,\n            \"raw_path\": request.url.raw_path.split(b\"?\", maxsplit=1)[0],\n            \"query_string\": request.url.query,\n            \"root_path\": \"\",\n            \"headers\": [(name.lower(), value) for name, value in request.headers.raw],\n            \"server\": (request.url.host, request.url.port),\n            \"client\": (\"127.0.0.1\", 1234),","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/PrefectHQ/fastmcp/blob/1f021142978e0861cd910c8df4e8074bc7cf3978/fastmcp_slim/fastmcp/utilities/asgi_transport.py#L112-L148","documentation":"StreamingASGITransport only supports httpx AsyncByteStream request bodies. If the incoming httpx Request carries a synchronous or non-stream body object, the transport raises TypeError because it cannot iterate the stream asynchronously.","triggerScenarios":"Passing an httpx Request whose .stream is not an httpx.AsyncByteStream instance into a client configured with StreamingASGITransport, e.g. building requests manually with a sync byte stream or bytes wrapper.","commonSituations":"Custom httpx client construction with the wrong transport pairing; mixing httpx versions where stream classes differ; hand-rolled request objects in tests.","solutions":["Ensure the request body is an httpx.AsyncByteStream (e.g. use async-compatible content)","Construct requests normally (httpx will use an async stream for async clients)","Check that the same httpx version/module is used for request and transport"],"exampleFix":"// before\nrequest = httpx.Request(\"POST\", url, content=b\"data\")\n\n// after\nasync def gen():\n    yield b\"data\"\nrequest = httpx.Request(\"POST\", url, content=gen())  # async stream","handlingStrategy":"type-guard","validationCode":"import httpx\nassert isinstance(request.stream, httpx.AsyncByteStream), \"need async stream\"","typeGuard":"def is_async_stream(r: httpx.Request) -> bool:\n    return isinstance(r.stream, httpx.AsyncByteStream)","tryCatchPattern":"try:\n    resp = await client.send(request)\nexcept TypeError as e:\n    if \"requires an async request stream\" in str(e):\n        request = httpx.Request(request.method, request.url, content=request.read())\n        resp = await client.send(request)\n    else:\n        raise","preventionTips":["Use httpx.AsyncClient so requests carry async streams","Avoid manually constructing Request objects for streaming transports","Pin one httpx version across the app"],"tags":["python","httpx","asgi","streaming"],"backgroundTag":"invalid-request-stream-type","analyzedSha":"1f021142978e0861cd910c8df4e8074bc7cf3978","analyzedAt":"2026-08-29T14:31:16.082Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}