pola-rs/polars · error · NotImplementedError

`collect_async` is not supported by

Error message

`collect_async` is not supported by {type(self).__name__}

What it means

`collect_async` is part of the `Engine` interface in polars' lazyframe engine module. The default/base engine implementation raises NotImplementedError because asynchronous execution is only provided by engines that support it (e.g. in-process async-capable engines or the streaming remote engine). Calling it on an engine lacking async support produces this error.

Solutions

  1. Use a supported engine, e.g. `lf.collect(engine='in-memory')` or use `collect_async` with an engine that implements it (the async-capable in-process engine).
  2. Replace `collect_async` with synchronous `lf.collect(optimizations=...)` in a thread if you only need non-blocking behavior.
  3. If you wrote a custom Engine, implement `collect_async` to return an `AsyncResult` for your backend.
  4. Check `isinstance(engine, ...)`/docs to confirm which async operations your engine supports.

Example fix

// before
await lf.collect_async(engine="streaming")  # engine lacks collect_async
// after
df = lf.collect(engine="in-memory")
Defensive patterns

Strategy: try-catch

Validate before calling

if not hasattr(type(engine_obj), "collect_async") or type(engine_obj).collect_async is Engine.collect_async:
    # fall back to sync collect

Type guard

def supports_async(engine: object) -> bool:
    return type(engine).collect_async is not Engine.collect_async

Try / catch

try:
    result = lf.collect_async(engine=eng)
except NotImplementedError:
    result = lf.collect(engine="in-memory")

Prevention

When it happens

Trigger: Calling `LazyFrame.collect_async(engine=...)` (or `lf.collect_async()` via `CollectEngine`) with an engine class that does not override `collect_async`, e.g. a custom/user-defined engine or one whose base implementation was hit.

Common situations: Implementing a custom `Engine` subclass without overriding `collect_async`; passing an engine name that resolves to a base-class engine; code copied from async examples run with a different engine selection.

Related errors


AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18). Data as JSON: /api/errors/ddd5498b31fb8d6c. Report an issue: GitHub.

Appendix: source

Thrown at py-polars/src/polars/lazyframe/engine.py:151

        This method of materializing a `LazyFrame` makes no guarantees as to where
        the result is materialized. This can be on the GPU for the GPU-engine,
        on the cluster or remote storage for the distributed engine and the streaming
        engine could spill the result if it needed to.

        The `QueryResult` can always be consumed as a new `LazyFrame` by calling `.lazy`
        """

    def collect_async(
        self,
        lf: LazyFrame,
        *,
        optimizations: QueryOptFlags,
        gevent: bool = False,
    ) -> AsyncResult[DataFrame]:
        """Execute `lf` asynchronously."""
        msg = f"`collect_async` is not supported by {type(self).__name__}"
        raise NotImplementedError(msg)

    def collect_batches(
        self,
        lf: LazyFrame,
        *,
        optimizations: QueryOptFlags,
        maintain_order: bool = True,
        chunk_size: int | None = None,
        lazy: bool = False,
    ) -> _CollectBatches:
        """Execute `lf`, yielding its result in batches."""
        msg = f"`collect_batches` is not supported by {type(self).__name__}"
        raise NotImplementedError(msg)

    def collect_all(
        self, lfs: Iterable[LazyFrame], *, optimizations: QueryOptFlags
    ) -> list[DataFrame]:
        """Execute several queries, potentially in parallel."""

View on GitHub (pinned to fe841f959e)