zylon-ai/private-gpt · error · AsyncIteratorError

Iterator next() operation failed: {e!s}

Error message

Iterator next() operation failed: {e!s}

What it means

Wrapped as AsyncIteratorError by to_async_iterator when calling next() on the underlying synchronous iterator raises any exception other than StopIteration. The next() call runs in a thread-pool executor via loop.run_in_executor; any error raised by the source iterator's __next__ (I/O error, parsing error, or a bug in the generator) propagates and is re-raised with this message, chaining the original cause.

Source

Thrown at private_gpt/utils/async_utils.py:68

            # Process items in chunks for better performance
            chunk = []
            for _ in range(chunk_size):
                try:

                    def safe_next(it: Iterator[T]) -> T:
                        try:
                            return next(it)
                        except StopIteration:
                            return None  # type: ignore

                    item = await loop.run_in_executor(
                        internal_executor, safe_next, iterator
                    )
                    if item is None:  # Handle StopIteration gracefully
                        break
                    chunk.append(item)
                except Exception as e:
                    raise AsyncIteratorError(
                        f"Iterator next() operation failed: {e!s}"
                    ) from e

            if not chunk:
                break

            # Process the chunk
            for item in chunk:
                try:
                    if transform_fn:
                        # Run transform in executor if it's CPU-intensive
                        result = await loop.run_in_executor(
                            internal_executor, transform_fn, item
                        )
                        yield result
                    else:
                        yield item
                except Exception as e:

View on GitHub (pinned to 4a030776a3)

Solutions

  1. Inspect the chained original exception (raise ... from e) - fix the root cause in the source iterator, not the wrapper
  2. Make the source iterator defensive: catch expected errors inside it and skip/log bad items instead of raising
  3. Ensure generators never let StopIteration escape from inside (PEP 479) - catch it and return explicitly
  4. If iterating a shared/closable resource, verify it is still open before yielding each item

Example fix

# before
def docs():
    for f in paths:
        yield parse(f.read())  # raises if f missing -> AsyncIteratorError

# after
def docs():
    for f in paths:
        try:
            yield parse(f.read())
        except OSError as e:
            logger.warning(f"skipping {f}: {e}")
            continue
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

from private_gpt.utils.async_utils import AsyncIteratorError

try:
    async for item in to_async_iterator(iter(docs)):
        process(item)
except AsyncIteratorError as e:
    root = e.__cause__  # the real next() failure
    logger.error("source iterator failed: %s", root, exc_info=root)

Prevention

When it happens

Trigger: Passing a generator that reads files or hits the network and raises mid-iteration; passing an already-exhausted/closed generator whose next() raises RuntimeError (generator raised StopIteration internally, PEP 479); an iterator over a DB cursor whose connection dropped; a map/filter chain whose underlying callable throws on a specific item.

Common situations: Streaming ingestion from a source that fails partway (S3 object deleted, socket reset); iterators built over LangChain document loaders that raise on malformed documents; reusing a generator after it was closed; transform pipelines where an earlier exception surfaces only when the item is pulled.

Related errors


AI-assisted analysis of zylon-ai/private-gpt@4a030776a3 (2026-08-15). Data as JSON: /api/errors/05b551f60e42ea05. Report an issue: GitHub.