pola-rs/polars · error · NoDataError

empty Excel sheet If you want to read this as an empty…

Error message

empty Excel sheet

If you want to read this as an empty DataFrame, set `raise_if_empty=False`.

What it means

The target Excel/ODS sheet contains no data rows, and polars refuses to silently return an empty DataFrame unless the caller opted out with `raise_if_empty=False`. `_empty_frame` is invoked by the openpyxl reader, null-dropping cleanup, and the CSV-buffer path when a sheet turns out to be blank. This makes truly-empty input an explicit, catchable NoDataError.

Solutions

  1. Pass `raise_if_empty=False` to read_excel to get an empty DataFrame instead of an error.
  2. Catch `polars.exceptions.NoDataError` and skip/handle empty sheets.
  3. Before reading, check the sheet has data (e.g. via openpyxl `ws.max_row`) and skip blank tabs.

Example fix

// before
pl.read_excel('report.xlsx', sheet_name='summary')  # NoDataError if blank
// after
pl.read_excel('report.xlsx', sheet_name='summary', raise_if_empty=False)
// or: try: ... except pl.exceptions.NoDataError: df = pl.DataFrame()
Defensive patterns

Strategy: try-catch

Validate before calling

import openpyxl
ws = openpyxl.load_workbook(path, read_only=True)[sheet_name]
if ws.max_row is None or ws.max_row < 1:
    df = pl.DataFrame()  # skip read entirely

Try / catch

try:
    df = pl.read_excel(path, sheet_name=sheet_name)
except pl.exceptions.NoDataError:
    df = pl.DataFrame()  # or: pass raise_if_empty=False upfront

Prevention

When it happens

Trigger: `pl.read_excel('empty.xlsx')` on a sheet with no used range; a sheet containing only formatting; reading a sheet whose rows are all null (dropped by _drop_null_data); passing sheet_name pointing at a blank tab with the default raise_if_empty=True.

Common situations: Templates with header-only or blank sheets; generated workbooks where a step wrote no data; iterating over many sheets where some are empty.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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

Appendix: source

Thrown at py-polars/src/polars/io/spreadsheet/functions.py:1013

                ):
                    null_cols.append(col_name)
        if null_cols:
            df = df.drop(*null_cols)

    if df.height == df.width == 0:
        return _empty_frame(raise_if_empty)
    if drop_empty_rows:
        return df.filter(~F.all_horizontal(F.all().is_null()))
    return df


def _empty_frame(raise_if_empty: bool) -> pl.DataFrame:  # noqa: FBT001
    if raise_if_empty:
        msg = (
            "empty Excel sheet"
            "\n\nIf you want to read this as an empty DataFrame, set `raise_if_empty=False`."
        )
        raise NoDataError(msg)
    return pl.DataFrame()


def _reorder_columns(
    df: pl.DataFrame, columns: Sequence[int] | Sequence[str] | None
) -> pl.DataFrame:
    if columns:
        from polars.selectors import by_index, by_name

        cols = (
            by_index(*columns)
            if is_non_empty_sequence_of(columns, int)
            else by_name(*columns)
        )
        df = df.select(cols)
    return df

View on GitHub (pinned to fe841f959e)