{"record":{"id":"53ed15434907002f","repo":"reflex-dev/reflex","slug":"stopasynciteration","errorCode":null,"errorMessage":"StopAsyncIteration","messagePattern":"StopAsyncIteration","errorType":"exception","errorClass":"StopAsyncIteration","httpStatus":null,"severity":"info","filePath":"packages/reflex-components-core/src/reflex_components_core/core/_upload.py","lineNumber":180,"sourceCode":"        Returns:\n            The next upload chunk.\n\n        Raises:\n            _error: Any error forwarded from the upload producer.\n            StopAsyncIteration: When all chunks have been consumed.\n        \"\"\"\n        async with self._condition:\n            while not self._chunks and not self._closed:\n                await self._condition.wait()\n\n            if self._chunks:\n                chunk = self._chunks.popleft()\n                self._condition.notify_all()\n                return chunk\n\n            if self._error is not None:\n                raise self._error\n            raise StopAsyncIteration\n\n    def set_consumer_task(self, task: asyncio.Future[Any]) -> None:\n        \"\"\"Track the task consuming this iterator.\n\n        Args:\n            task: The background task consuming upload chunks.\n        \"\"\"\n        self._consumer_task = task\n        task.add_done_callback(self._wake_waiters)\n\n    async def push(self, chunk: UploadChunk) -> None:\n        \"\"\"Push a new chunk into the iterator.\n\n        Args:\n            chunk: The chunk to push.\n\n        Raises:\n            RuntimeError: If the iterator is already closed or the consumer exited early.","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-components-core/src/reflex_components_core/core/_upload.py#L162-L198","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Use `async for chunk in iter` which handles StopAsyncIteration automatically","If calling __anext__ manually, catch StopAsyncIteration to detect end of stream","Break out of the loop once you've processed the expected file size"],"exampleFix":"// before\nwhile True:\n    chunk = await it.__anext__()  # raises at end\n\n// after\nasync for chunk in it:\n    process(chunk)","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use async for over the iterator rather than manual __anext__","Treat StopAsyncIteration as end-of-stream, not a failure"],"tags":["upload","async-iteration","control-flow"],"backgroundTag":"stop-async-iteration","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}