pola-rs/polars · error · TypeError
cannot describe a LazyFrame that has no columns
Error message
cannot describe a LazyFrame that has no columns
What it means
LazyFrame.describe() builds summary statistics per column, so it needs at least one column. If collect_schema() returns an empty schema (zero columns), polars raises TypeError rather than returning an empty table. This can only happen when the lazy plan itself selects zero columns, e.g. after select() of an empty list or reading an empty/edge-case source.
Source
Thrown at py-polars/src/polars/lazyframe/frame.py:1102
│ null_count ┆ 0.0 ┆ 1.0 ┆ 0.0 ┆ 0 ┆ 0 ┆ 0 │
│ mean ┆ 2.266667 ┆ 45.0 ┆ 0.666667 ┆ null ┆ 2021-07-02 16:00:00 ┆ 16:07:10 │
│ std ┆ 1.101514 ┆ 7.071068 ┆ null ┆ null ┆ null ┆ null │
│ min ┆ 1.0 ┆ 40.0 ┆ 0.0 ┆ xx ┆ 2020-01-01 ┆ 10:20:30 │
│ 10% ┆ 1.36 ┆ 41.0 ┆ null ┆ null ┆ 2020-04-20 ┆ 11:13:34 │
│ 30% ┆ 2.08 ┆ 43.0 ┆ null ┆ null ┆ 2020-11-26 ┆ 12:59:42 │
│ 50% ┆ 2.8 ┆ 45.0 ┆ null ┆ null ┆ 2021-07-05 ┆ 14:45:50 │
│ 70% ┆ 2.88 ┆ 47.0 ┆ null ┆ null ┆ 2022-02-07 ┆ 18:09:34 │
│ 90% ┆ 2.96 ┆ 49.0 ┆ null ┆ null ┆ 2022-09-13 ┆ 21:33:18 │
│ max ┆ 3.0 ┆ 50.0 ┆ 1.0 ┆ zz ┆ 2022-12-31 ┆ 23:15:10 │
└────────────┴──────────┴──────────┴──────────┴──────┴─────────────────────┴──────────┘
""" # noqa: W505
from polars.convert import from_dict
schema = self.collect_schema()
if not schema:
msg = "cannot describe a LazyFrame that has no columns"
raise TypeError(msg)
# create list of metrics
metrics = ["count", "null_count", "mean", "std", "min"]
if quantiles := parse_percentiles(percentiles):
metrics.extend(f"{q * 100:g}%" for q in quantiles)
metrics.append("max")
@lru_cache
def skip_minmax(dt: PolarsDataType) -> bool:
return (
dt.is_nested()
or dt.is_extension()
or dt in (Categorical, Enum, Null, Object, Unknown)
)
# determine which columns will produce std/mean/percentile/etc
# statistics in a single pass over the frame schema
has_numeric_result, sort_cols = set(), set()View on GitHub (pinned to df599052da)
Solutions
- Inspect lf.collect_schema().names() to see why the plan has no columns
- Guard: if len(lf.collect_schema()) == 0, skip describe or fix the pipeline upstream
- Fix the select()/selector logic so at least one column survives
- If columns are chosen dynamically, fall back to a known column list when selection is empty
Example fix
# before
stats = lf.select(cs.numeric()).describe() # may have zero columns
# after
num = cs.numeric()
if len(lf.select(num).collect_schema()) > 0:
stats = lf.select(num).describe()
else:
stats = None Defensive patterns
Strategy: validation
Validate before calling
if len(lf.collect_schema().names()) == 0:
raise ValueError('pipeline produced a LazyFrame with no columns')
stats = lf.describe() Type guard
def has_columns(lf) -> bool:
return len(lf.collect_schema()) > 0 Try / catch
try:
stats = lf.describe()
except TypeError:
stats = None # or fix upstream column selection Prevention
- Assert non-empty schema right after dynamic select() calls
- Log lf.collect_schema().names() at pipeline boundaries
- Test selectors against representative schemas
When it happens
Trigger: lf.select([]).describe(); scanning a file whose schema resolution yields no columns; a pipeline step that drops all columns (e.g. select with a selector that matches nothing, like cs.numeric() on an all-string frame).
Common situations: Dynamic column selection with selectors that match zero columns; empty test fixtures; data files with unexpected schemas after an upstream change.
Related errors
- negative stop is not supported for lazy slices
- negative stride is not supported in conjunction with start+s
- the given slice {s!r} is not supported by lazy computation\n
- `percentiles` must all be in the range [0, 1]
- cannot describe a DataFrame that has no columns
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/de28a7cb9b747063.
Report an issue: GitHub.