reflex-dev/reflex · info · StopAsyncIteration

StopAsyncIteration

Error message

StopAsyncIteration

What it means

Standard StopAsyncIteration raised by the async upload chunk iterator's __anext__ when the stream is exhausted (no more chunks, no pending error). This is the normal protocol signal that terminates `async for` loops over uploaded file chunks in streaming upload handlers.

Source

Thrown at packages/reflex-components-core/src/reflex_components_core/core/_upload.py:180

        Returns:
            The next upload chunk.

        Raises:
            _error: Any error forwarded from the upload producer.
            StopAsyncIteration: When all chunks have been consumed.
        """
        async with self._condition:
            while not self._chunks and not self._closed:
                await self._condition.wait()

            if self._chunks:
                chunk = self._chunks.popleft()
                self._condition.notify_all()
                return chunk

            if self._error is not None:
                raise self._error
            raise StopAsyncIteration

    def set_consumer_task(self, task: asyncio.Future[Any]) -> None:
        """Track the task consuming this iterator.

        Args:
            task: The background task consuming upload chunks.
        """
        self._consumer_task = task
        task.add_done_callback(self._wake_waiters)

    async def push(self, chunk: UploadChunk) -> None:
        """Push a new chunk into the iterator.

        Args:
            chunk: The chunk to push.

        Raises:
            RuntimeError: If the iterator is already closed or the consumer exited early.

View on GitHub (pinned to 45b8ed5ab7)

Solutions

  1. Use `async for chunk in iter` which handles StopAsyncIteration automatically
  2. If calling __anext__ manually, catch StopAsyncIteration to detect end of stream
  3. Break out of the loop once you've processed the expected file size

Example fix

// before
while True:
    chunk = await it.__anext__()  # raises at end

// after
async for chunk in it:
    process(chunk)
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: The consumer loop keeps calling __anext__ after the producer finished and the internal chunk queue is empty — i.e. the natural end of an `async for chunk in upload_file(...)` stream.

Common situations: Not an error per se; developers see it when manually calling __anext__() outside an async for, or when the loop logic calls next on an already-drained iterator.

Related errors


AI-assisted analysis of reflex-dev/reflex@45b8ed5ab7 (2026-08-28). Data as JSON: /api/errors/53ed15434907002f. Report an issue: GitHub.