BerriAI/litellm · error · TypeError
File content stream does not support sync iteration
Error message
File content stream does not support sync iteration
What it means
FileContentStreamingResponse wraps the raw provider iterator returned by file-content retrieval. __iter__ checks that the wrapped stream_iterator exposes __next__ (a sync iterator); if the provider returned an async-only iterator (it only has __anext__), sync iteration with `for chunk in response` raises TypeError.
Source
Thrown at litellm/files/streaming.py:49
self.stream_iterator = stream_iterator
self.file_id = file_id
self.model = model
self.custom_llm_provider = custom_llm_provider
self.logging_obj = logging_obj
self.standard_logging_object: StandardLoggingPayload | None = None
self._hidden_params: dict[str, Any] = {}
self._logging_completed = False
self._close_completed = False
self._start_time = (
logging_obj.start_time
if logging_obj is not None and getattr(logging_obj, "start_time", None)
else datetime.datetime.now()
)
self._sync_hidden_params()
def __iter__(self) -> "FileContentStreamingResponse":
if not hasattr(self.stream_iterator, "__next__"):
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")View on GitHub (pinned to 6c2dcb801b)
Solutions
- Iterate the same flavor you created with: use async iteration (`async for chunk in response`) for async responses
- If you need sync bytes, make the original file-content call through the sync path so the wrapper gets a sync iterator
- Read the whole body once via the provided aclose()/read-style helpers on the async response instead of forcing sync iteration
Example fix
# before
resp = await client.files.acontent(fid) # async-backed stream
for chunk in resp: # TypeError
...
# after
async for chunk in resp:
... Defensive patterns
Strategy: type-guard
Validate before calling
if not hasattr(resp.stream_iterator, "__next__"):
raise TypeError("response is async-only; use `async for`") Type guard
def is_sync_stream(resp) -> bool:
return hasattr(resp.stream_iterator, "__next__") Try / catch
try:
for chunk in resp: process(chunk)
except TypeError as e:
if "sync iteration" in str(e):
asyncio.run(consume_async(resp)) Prevention
- Keep retrieval and consumption in the same sync/async flavor
- Write helpers that check the iterator protocol before looping
When it happens
Trigger: Iterating the returned streaming response synchronously when the underlying call was async — e.g. holding a response produced via the async file-content path and then calling iter()/next() or a `for` loop over it inside sync code.
Common situations: Mixing sync and async lifecycles (async with ... : resp = await acreate_file_content... then sync iteration); passing an httpx.AsyncClient-produced byte stream into the sync wrapper; test helpers that iterate without regard to flavor.
Related errors
- File content stream does not support async iteration
- Use AsyncGoogleGenAIGenerateContentStreamingIterator for asy
- Braintrust API error: {e.response.text}
- Failed to connect to Braintrust API: {str(e)}
- api_base is required for Pydantic AI agents
AI-assisted analysis of BerriAI/litellm@6c2dcb801b (2026-08-15).
Data as JSON: /api/errors/39d6ffa49d431db8.
Report an issue: GitHub.