pola-rs/polars · error · NoDataError
no data found in the given workbook(s) and sheet(s)
Error message
no data found in the given workbook(s) and sheet(s)
What it means
polars.exceptions.NoDataError raised by _unpack_read_results after reading Excel sources: the read completed but produced zero DataFrames. This happens when every selected sheet parsed to nothing — e.g. sheets whose rows were all dropped by drop_empty_rows/drop_empty_cols — so there is no frame to return or concatenate.
Source
Thrown at py-polars/src/polars/io/spreadsheet/functions.py:99
src = str(src)
sources.append(src)
return sources, read_multiple_workbooks
def _standardize_duplicates(s: str) -> str:
"""Standardize columns with '_duplicated_n' names."""
return re.sub(r"_duplicated_(\d+)", repl=r"\1", string=s)
def _unpack_read_results(
frames: list[pl.DataFrame] | list[dict[str, pl.DataFrame]],
*,
read_multiple_workbooks: bool,
) -> Any:
if not frames:
msg = "no data found in the given workbook(s) and sheet(s)"
raise NoDataError(msg)
if not read_multiple_workbooks:
# one sheet from one workbook
return frames[0]
if isinstance(frames[0], pl.DataFrame):
# one sheet from multiple workbooks
return concat(frames, how="vertical_relaxed") # type: ignore[type-var]
else:
# multiple sheets from multiple workbooks
sheet_frames = defaultdict(list)
for res in frames:
for sheet, df in res.items(): # type: ignore[union-attr]
sheet_frames[sheet].append(df)
return {k: concat(v, how="vertical_relaxed") for k, v in sheet_frames.items()}
@overloadView on GitHub (pinned to df599052da)
Solutions
- Inspect the workbook and confirm the target sheet actually contains data (check it in Excel/another reader).
- Handle the empty case explicitly: wrap in try/except NoDataError and substitute an explicit empty schema or skip processing, rather than letting the exception kill the job.
- Tighten glob patterns or sheet selection (sheet_name/sheet_id) so blank placeholder sheets are not read.
- If blank-looking rows matter, revisit drop_empty_rows=False / raise_if_empty-style handling.
Example fix
# before
df = pl.read_excel('report.xlsx') # NoDataError when sheet is blank
# after
try:
df = pl.read_excel('report.xlsx')
except pl.exceptions.NoDataError:
df = pl.DataFrame(schema={'date': pl.Date, 'amount': pl.Float64}) # explicit empty result Defensive patterns
Strategy: try-catch
Validate before calling
# Optional pre-check that the target sheet has any non-empty cells (needs openpyxl):
from openpyxl import load_workbook
wb = load_workbook(path, read_only=True)
has_any = any(cell.value is not None for row in wb[sheet].iter_rows() for cell in row)
if not has_any:
df = pl.DataFrame(schema=expected_schema) # skip the read
else:
df = pl.read_excel(path, sheet_name=sheet) Try / catch
try:
df = pl.read_excel(path, sheet_name=sheet)
except pl.exceptions.NoDataError:
df = pl.DataFrame(schema=expected_schema) # explicit, typed empty result
log.warning('workbook %s sheet %s contained no data', path, sheet) Prevention
- Treat empty workbooks as an expected input state for scheduled/ETL reads, not an exception.
- Standardize an empty-frame fallback with an explicit schema so downstream code stays typed.
- Tighten glob patterns and sheet selection so blank template sheets are never selected.
When it happens
Trigger: pl.read_excel('empty.xlsx') where the sheet has only blank rows and drop_empty_rows=True (default); reading multiple workbooks via glob where every matched file is empty; sheet combinations that select only blank sheets.
Common situations: Scheduled jobs reading a periodically-generated report that is occasionally empty; templates with header-only or whitespace-only sheets; glob patterns matching both data files and blank placeholder files.
Related errors
- no workbook found at path {src!r}
- no matching sheets found when `sheet_{param}` is {value!r}
- cannot specify both `columns` and `read_options["use_columns
- the values of `has_header` and `read_options["header_row"]`
- cannot specify both `infer_schema_length` and `read_options[
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/01503a5877f486ed.
Report an issue: GitHub.