{"record":{"id":"55e4821b0cf492d1","repo":"reflex-dev/reflex","slug":"upload-chunk-iterator-is-closed","errorCode":null,"errorMessage":"Upload chunk iterator is closed.","messagePattern":"Upload chunk iterator is closed\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"packages/reflex-components-core/src/reflex_components_core/core/_upload.py","lineNumber":207,"sourceCode":"        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.\n        \"\"\"\n        async with self._condition:\n            while len(self._chunks) >= self._maxsize and not self._closed:\n                self._raise_if_consumer_finished()\n                await self._condition.wait()\n\n            if self._closed:\n                msg = \"Upload chunk iterator is closed.\"\n                raise RuntimeError(msg)\n\n            self._raise_if_consumer_finished()\n            self._chunks.append(chunk)\n            self._condition.notify_all()\n\n    async def finish(self) -> None:\n        \"\"\"Mark the iterator as complete.\"\"\"\n        async with self._condition:\n            if self._closed:\n                return\n            self._closed = True\n            self._condition.notify_all()\n\n    async def fail(self, error: Exception) -> None:\n        \"\"\"Mark the iterator as failed.\n\n        Args:\n            error: The error to raise from the iterator.","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/reflex-dev/reflex/blob/45b8ed5ab735f8a56bbb09a42384f030eb0208e7/packages/reflex-components-core/src/reflex_components_core/core/_upload.py#L189-L225","documentation":"The upload chunk iterator is a bounded queue; push() blocks while full and raises RuntimeError if the queue was closed (upload finished or aborted) while a producer was blocked or about to enqueue. This prevents writing chunks after the consumer is gone.","triggerScenarios":"Server-side upload machinery pushes a chunk after iterator.close() was called — typically when the client disconnected, the handler returned early, or the request was cancelled mid-stream.","commonSituations":"Client aborts a large file upload mid-transfer; websocket/http disconnect while chunks are still being forwarded; handler breaks out of the loop before draining the iterator.","solutions":["Ensure the upload handler consumes the full iterator (don't break early on partial reads)","Handle client disconnects upstream so the parser stops pushing chunks","Catch RuntimeError around push/consume loops in custom upload plumbing and treat it as cancellation"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    await iterator.push(chunk)\nexcept RuntimeError:\n    # upload closed (disconnect/finish) — stop producing\n    abort_parse()","preventionTips":["Drain the iterator fully in handlers","Propagate client disconnects so pushing stops"],"tags":["upload","streaming","lifecycle"],"backgroundTag":"stream-closed-write","analyzedSha":"45b8ed5ab735f8a56bbb09a42384f030eb0208e7","analyzedAt":"2026-08-28T19:25:27.644Z","schemaVersion":2},"datasetVersion":"2026-08-28T21:17:43.275Z"}