aio-libs/aiohttp · error · TypeError
value argument must support collections.abc.AsyncIterable in
Error message
value argument must support collections.abc.AsyncIterable interface, got {type(value)!r} What it means
Raised by AsyncIterablePayload.__init__ when the supplied value does not implement collections.abc.AsyncIterable. aiohttp uses this payload type to stream request/response bodies from an async producer, so it strictly requires an object with a working __aiter__/__anext__ protocol. Passing a plain list, a synchronous generator, bytes, or any non-async iterable triggers it. The error message reports the actual type via {type(value)!r} for diagnosis.
Source
Thrown at aiohttp/payload.py:985
) -> None:
super().__init__(
dumps(value),
content_type=content_type,
*args,
**kwargs,
)
class AsyncIterablePayload(Payload):
_iter: AsyncIterator[bytes] | None = None
_value: AsyncIterable[bytes]
_cached_chunks: list[bytes] | None = None
# _consumed stays False to allow reuse with cached content
_autoclose = True # Iterator doesn't need explicit closing
def __init__(self, value: AsyncIterable[bytes], *args: Any, **kwargs: Any) -> None:
if not isinstance(value, AsyncIterable):
raise TypeError(
"value argument must support "
"collections.abc.AsyncIterable interface, "
f"got {type(value)!r}"
)
if "content_type" not in kwargs:
kwargs["content_type"] = "application/octet-stream"
super().__init__(value, *args, **kwargs)
self._iter = value.__aiter__()
async def write(self, writer: AbstractStreamWriter) -> None:
"""
Write the entire async iterable payload to the writer stream.
Args:
writer: An AbstractStreamWriter instance that handles the actual writingView on GitHub (pinned to c0ef574e29)
Solutions
- Pass an async iterable: an async generator function CALLED (e.g. async_gen()), an object implementing __aiter__, or an aiohttp.StreamReader.
- If you only have a sync iterator, wrap it: async def gen(): for chunk in sync_iter: yield chunk, then pass gen().
- For bytes/str already fully materialized, use BytesPayload (or just pass data=bytes) instead of AsyncIterablePayload.
- Register a custom Payload subclass via PAYLOAD_REGISTRY.register(MyPayload, MyType) if you need first-class support for your type.
Example fix
// before
async def producer():
for chunk in chunks: # sync loop, not async
yield chunk
payload = AsyncIterablePayload(producer())
// after
async def producer():
for chunk in chunks:
yield chunk # still works only if it is `async def`
payload = AsyncIterablePayload(producer())
# Or, for already-materialized bytes:
from aiohttp import payload
p = payload.BytesPayload(b'data') Defensive patterns
Strategy: type-guard
Validate before calling
from collections.abc import AsyncIterable
def is_async_iterable(obj) -> bool:
return isinstance(obj, AsyncIterable)
# before constructing:
if not is_async_iterable(value):
raise TypeError(f'expected async iterable, got {type(value).__name__}')
payload = AsyncIterablePayload(value) Type guard
from collections.abc import AsyncIterable
from typing import Any, TypeGuard
def is_async_iterable(obj: Any) -> TypeGuard[AsyncIterable[bytes]]:
return isinstance(obj, AsyncIterable) Try / catch
from collections.abc import AsyncIterable
try:
payload = AsyncIterablePayload(value)
except TypeError:
# fall back to materializing the body
payload = BytesPayload(bytes(value)) Prevention
- Always pass async generators (called) or objects implementing __aiter__.
- Register a custom Payload+type via PAYLOAD_REGISTRY for domain types.
- Add a runtime isinstance(value, AsyncIterable) assert in test fixtures.
When it happens
Trigger: Constructing AsyncIterablePayload(value) directly, or calling aiohttp.payload.get_payload()/payload_type() on an object that is not async iterable (e.g. a sync generator function, list, tuple, bytes, or a custom class lacking __aiter__). Also triggered indirectly by passing such an object as the data= argument to web.Response or client session methods when its class is not registered with PAYLOAD_REGISTRY.
Common situations: Developers migrating from requests/httpx who pass a sync generator to stream a body; passing a list of bytes chunks; using an async generator function object instead of the called coroutine (forgot parentheses); wrapping a sync file object instead of an aiohttp or aiofiles async reader.
Related errors
- Unable to decode.
- Unable to read body part as bytes. Use write() to consume.
- Unable to decode - content not cached. Call as_bytes() first
- Cannot follow redirect with a consumed request body. Use byt
- Can not serialize value type: %r headers: %r value: %r
AI-assisted analysis of aio-libs/aiohttp@c0ef574e29 (2026-08-04).
Data as JSON: /data/errors/d67425664e5566f3.json.
Report an issue: GitHub.