BerriAI/litellm · error · TypeError

File content stream does not support async iteration

Error message

File content stream does not support async iteration

What it means

The async mirror of the sync guard: __aiter__ verifies stream_iterator implements __anext__. If the underlying provider stream is sync-only (only __next__), `async for chunk in response` raises TypeError because there is nothing to asynchronously await.

Source

Thrown at litellm/files/streaming.py:67

            raise TypeError("File content stream does not support sync iteration")
        return self

    def __next__(self) -> bytes:
        if not hasattr(self.stream_iterator, "__next__"):
            raise TypeError("File content stream does not support sync iteration")

        try:
            return next(cast(Iterator[bytes], self.stream_iterator))
        except StopIteration:
            self._log_success_sync()
            raise
        except Exception as e:
            self._log_failure_sync(e)
            raise

    def __aiter__(self) -> "FileContentStreamingResponse":
        if not hasattr(self.stream_iterator, "__anext__"):
            raise TypeError("File content stream does not support async iteration")
        return self

    async def __anext__(self) -> bytes:
        if not hasattr(self.stream_iterator, "__anext__"):
            raise TypeError("File content stream does not support async iteration")

        try:
            return await cast(AsyncIterator[bytes], self.stream_iterator).__anext__()
        except StopAsyncIteration:
            await self._log_success_async()
            raise
        except Exception as e:
            await self._log_failure_async(e)
            raise

    async def aclose(self) -> None:
        if self._close_completed:
            return

View on GitHub (pinned to 6c2dcb801b)

Solutions

  1. Use the async file-content retrieval so the wrapper holds an async iterator, then `async for chunk in response`
  2. If you must bridge, wrap the sync iterator with a thread-based async adapter or read it fully to bytes before entering async code
  3. Check hasattr(resp.stream_iterator, '__anext__') before choosing the loop flavor

Example fix

# before
resp = litellm.file_content(fid, custom_llm_provider='openai')  # sync stream
async for chunk in resp:  # TypeError
    ...

# after
resp = await litellm.afile_content(fid, custom_llm_provider='openai')
async for chunk in resp:
    ...
Defensive patterns

Strategy: type-guard

Validate before calling

if not hasattr(resp.stream_iterator, "__anext__"):
    raise TypeError("response is sync-only; use `for`")

Type guard

from collections.abc import AsyncIterator

def is_async_stream(resp) -> bool:
    return hasattr(resp.stream_iterator, "__anext__") and not isinstance(resp.stream_iterator, AsyncIterator) is False

Try / catch

try:
    async for chunk in resp: await process(chunk)
except TypeError as e:
    if "async iteration" in str(e):
        for chunk in resp: process_sync(chunk)

Prevention

When it happens

Trigger: Using `async for` over a FileContentStreamingResponse created from a synchronous file-content call (sync httpx stream wrapped by the sync path); awaiting iteration on a response obtained without an async client.

Common situations: Porting sync example code into an async FastAPI handler and changing only the loop to `async for` while keeping the sync retrieval call; mixing litellm sync file APIs inside async endpoints for 'convenience'.

Related errors


AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15). Data as JSON: /api/errors/37c5c98bd1b18986. Report an issue: GitHub.