Fix: Improve error message when polars LazyFrame is passed to check_array

Fixed scikit-learn/scikit-learn#34258 — 6 line bug-fix adding explicit TypeError for polars LazyFrame.

The Bug

Repo: scikit-learn/scikit-learn Issue: #34258 Status: PR-submitted PR: https://github.com/scikit-learn/scikit-learn/pull/34478

Description: When a polars LazyFrame is passed to scikit-learn’s check_array(), the error message is confusing because it doesn’t clearly explain that lazy dataframes are not supported.

Fix scope: 6 lines changed in sklearn/utils/validation.py

Root Cause

Polars has two distinct DataFrame modes: eager (DataFrame) and lazy (LazyFrame). Eager DataFrames contain materialized data and can be converted to numpy arrays directly. LazyFrames, on the other hand, represent a query plan — the data hasn’t been executed yet. When passed to check_array(), the existing polars conversion path would attempt to convert the LazyFrame without executing it, producing confusing downstream errors.

The root issue is that scikit-learn’s validation layer, which already supported eager polars DataFrames through its array API integration, had no explicit detection for the lazy variant. Users would see an opaque error about array conversion failures rather than a clear message about the unsupported lazy type.

Impact: Medium. Users integrating scikit-learn with polars pipelines — especially those using polars’ lazy API for query optimization — would hit a confusing error boundary. The fix doesn’t enable LazyFrame support (that would require calling .collect() internally, which could be a surprising side effect), but it does surface a clear, actionable error message telling the user exactly what to do.

The Fix

Added an explicit type check for polars LazyFrame before the general array validation path:

if nw.dependencies.is_into_lazyframe(array):
    raise TypeError(
        "A polars LazyFrame was passed, but lazy dataframes are not supported."
        " Use '.collect()' to convert it to a polars DataFrame."
    )

The fix uses nw.dependencies.is_into_lazyframe() from the narwhals library (which scikit-learn already depends on for array API interop). This check runs early in check_array() before any conversion attempt, so the user gets the error immediately with a specific remediation: call .collect().

Pattern & Takeaways

Pattern: Framework libraries that add support for an ecosystem type (like polars DataFrame) often miss its lazy variant because the eager version “just works” through the standard conversion path. Lazy types require explicit collection before downstream consumption.

Key insight: When integrating with a library that has lazy/eager duality, always check for both variants. LazyFrame, dask arrays, and similar deferred-execution types all need special handling — convert eagerly with a warning, or reject with a clear error message. The best practice is to detect early and reject with a helpful message rather than letting the user discover the limitation through a confusing downstream error.

Transfer Potential

High — the polars ecosystem is growing fast, and many Python data science libraries are adding polars support. Every library that accepts DataFrames needs to decide how to handle LazyFrame. The pattern of checking is_into_lazyframe() early and providing a .collect() hint is directly transferable. The same principle applies to any lazy/deferred type interface.


Auto-generated from PR #34258. View all patches on GitHub.

References

[1] scikit-learn/scikit-learn [2] #34258 [3] https://github.com/scikit-learn/scikit-learn/pull/34478