PrefectHQ/fastmcp · error · RuntimeError
Unexpected ASGI message type: {message['type']}
Error message
Unexpected ASGI message type: {message['type']} What it means
During ASGI response streaming, the transport's send_response handler accepts only 'http.response.start' and 'http.response.body' messages. Any other ASGI message type (e.g. lifecycle or websocket messages on an HTTP response path) triggers this RuntimeError.
Source
Thrown at fastmcp_slim/fastmcp/utilities/asgi_transport.py:181
request_delivered = True
return {
"type": "http.request",
"body": request_body,
"more_body": False,
}
await client_disconnected.wait()
return {"type": "http.disconnect"}
async def send_response(message: Message) -> None:
nonlocal response_status, response_headers, start_received
if message["type"] == "http.response.start":
start_received = True
response_status = message["status"]
response_headers = list(message.get("headers", []))
response_started.set()
return
if message["type"] != "http.response.body":
raise RuntimeError(f"Unexpected ASGI message type: {message['type']}")
body: bytes = message.get("body", b"")
if body:
await chunk_writer.send(body)
if not message.get("more_body", False):
await chunk_writer.aclose()
async def run_application() -> None:
nonlocal application_error
try:
await self._app(scope, receive_request, send_response)
except Exception as exc:
# The bridge is the application's outermost boundary: a crash must fail the
# originating request (or show up in the already-started response), never
# tear down the task group shared with every other in-flight request.
application_error = exc
finally:
response_started.set()
await chunk_writer.aclose()View on GitHub (pinned to 1f02114297)
Solutions
- Inspect the ASGI app/middleware for messages emitted outside the HTTP response contract
- Ensure the request scope is a plain HTTP request when using this transport
- Log the offending message['type'] to identify which component misbehaves
Defensive patterns
Strategy: try-catch
Validate before calling
# Ensure scope type is http before sending requests through the transport assert scope["type"] == "http"
Try / catch
try:
response = await client.send(request)
except RuntimeError as e:
if "Unexpected ASGI message type" in str(e):
logger.error("ASGI app emitted non-HTTP message: %s", e)
# inspect middleware / app message emission
else:
raise Prevention
- Audit custom ASGI middleware for message-type handling
- Test apps against the standard ASGI spec (asgiref compliance)
- Only use this transport for plain HTTP scopes
When it happens
Trigger: The ASGI app sends a message type other than http.response.start/body while the transport is reading the HTTP response, such as 'http.disconnect' misuse or websocket-scope messages.
Common situations: ASGI apps with buggy custom middleware sending non-HTTP messages; using the transport against a websocket or lifespan scope; framework upgrades changing message emission.
Related errors
- The client negotiated a modern protocol era (server/discover
- logging/setLevel is not available on MCP 2026-07-28 connecti
- StreamingASGITransport requires an async request stream; got
- module {__name__!r} has no attribute {name!r}
- Cannot resolve tool reference: {fn!r}
AI-assisted analysis of PrefectHQ/fastmcp@1f02114297 (2026-08-29).
Data as JSON: /api/errors/3d9f9b1f2ca96070.
Report an issue: GitHub.