PrefectHQ/fastmcp · error · TypeError

StreamingASGITransport requires an async request stream; got

Error message

StreamingASGITransport requires an async request stream; got {type(request.stream).__name__}.

What it means

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.

Source

Thrown at fastmcp_slim/fastmcp/utilities/asgi_transport.py:130

        await self._task_group.__aenter__()
        return self

    async def __aexit__(
        self,
        exc_type: type[BaseException] | None = None,
        exc_value: BaseException | None = None,
        traceback: TracebackType | None = None,
    ) -> None:
        # httpx closes every streamed response before closing the transport, so by now each
        # application task has been delivered `http.disconnect`. Either cancel immediately,
        # or wait for the application's own disconnect handling to unwind.
        if self._cancel_on_close:
            self._task_group.cancel_scope.cancel()
        await self._task_group.__aexit__(exc_type, exc_value, traceback)

    async def handle_async_request(self, request: httpx2.Request) -> httpx2.Response:
        if not isinstance(request.stream, httpx2.AsyncByteStream):
            raise TypeError(
                "StreamingASGITransport requires an async request stream; "
                f"got {type(request.stream).__name__}."
            )
        request_body = b"".join([chunk async for chunk in request.stream])

        scope: Scope = {
            "type": "http",
            "asgi": {"version": "3.0"},
            "http_version": "1.1",
            "method": request.method,
            "scheme": request.url.scheme,
            "path": request.url.path,
            "raw_path": request.url.raw_path.split(b"?", maxsplit=1)[0],
            "query_string": request.url.query,
            "root_path": "",
            "headers": [(name.lower(), value) for name, value in request.headers.raw],
            "server": (request.url.host, request.url.port),
            "client": ("127.0.0.1", 1234),

View on GitHub (pinned to 1f02114297)

Solutions

  1. Ensure the request body is an httpx.AsyncByteStream (e.g. use async-compatible content)
  2. Construct requests normally (httpx will use an async stream for async clients)
  3. Check that the same httpx version/module is used for request and transport

Example fix

// before
request = httpx.Request("POST", url, content=b"data")

// after
async def gen():
    yield b"data"
request = httpx.Request("POST", url, content=gen())  # async stream
Defensive patterns

Strategy: type-guard

Validate before calling

import httpx
assert isinstance(request.stream, httpx.AsyncByteStream), "need async stream"

Type guard

def is_async_stream(r: httpx.Request) -> bool:
    return isinstance(r.stream, httpx.AsyncByteStream)

Try / catch

try:
    resp = await client.send(request)
except TypeError as e:
    if "requires an async request stream" in str(e):
        request = httpx.Request(request.method, request.url, content=request.read())
        resp = await client.send(request)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: Custom httpx client construction with the wrong transport pairing; mixing httpx versions where stream classes differ; hand-rolled request objects in tests.

Related errors


AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29). Data as JSON: /api/errors/9f15af9f9911ca83. Report an issue: GitHub.