pola-rs/polars · error · RuntimeError

no named tables found in sheet

Error message

no named tables found in sheet {sheet_name!r} (looking for {table_name!r})

What it means

When reading with the openpyxl engine and `table_name` is given, if the worksheet exposes no table objects at all, polars raises this RuntimeError saying no named tables exist in the sheet (while naming the table that was being looked for). The sheet contains plain cell data, not a formal Excel table.

Solutions

  1. Drop `table_name` and read the sheet's used range directly: pl.read_excel('f.xlsx', sheet_name='Data').
  2. Or define a named table in Excel (select range > Insert > Table) and re-save.
  3. Or use the calamine engine with table_name after upgrading fastexcel>=0.12, once a real table exists.

Example fix

// before
pl.read_excel('f.xlsx', engine='openpyxl', sheet_name='Data', table_name='Sales')
// after
pl.read_excel('f.xlsx', engine='openpyxl', sheet_name='Data')  # no named table exists; read used range
Defensive patterns

Strategy: validation

Validate before calling

import openpyxl
ws = openpyxl.load_workbook(path)[sheet_name]
if not getattr(ws, 'tables', None):
    # no named tables: read the used range instead
    df = pl.read_excel(path, engine='openpyxl', sheet_name=sheet_name)

Try / catch

try:
    df = pl.read_excel(path, engine='openpyxl', table_name=table_name, sheet_name=sheet_name)
except RuntimeError as e:
    if 'no named tables found' in str(e):
        df = pl.read_excel(path, engine='openpyxl', sheet_name=sheet_name)
    else:
        raise

Prevention

When it happens

Trigger: `pl.read_excel('f.xlsx', engine='openpyxl', table_name='Table1', sheet_name='Data')` where `ws.tables` is empty/None — the data range was never defined as an Excel table.

Common situations: Sheets that are plain ranges with headers; CSV-derived xlsx files; assuming any header block counts as a 'table'; receiving workbooks from systems that don't create table objects.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

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

        ws = parser[sheet_name]

    # prefer detection of actual table objects; otherwise read
    # data in the used worksheet range, dropping null columns
    if tables := getattr(ws, "tables", None):
        table = tables[table_name] if table_name else next(iter(tables.values()))
        rows = list(ws[table.ref])
        if not rows:
            return _empty_frame(raise_if_empty)
        if has_header:
            header.extend(cell.value for cell in rows.pop(0))
        else:
            header.extend(f"column_{n}" for n in range(len(rows[0])))
        if table.totalsRowCount:
            rows = rows[: -table.totalsRowCount]
        rows_iter = rows
    elif table_name:
        msg = f"no named tables found in sheet {sheet_name!r} (looking for {table_name!r})"
        raise RuntimeError(msg)
    else:
        if not has_header:
            if not (rows_iter := list(ws.iter_rows())):
                return _empty_frame(raise_if_empty)
            n_cols = len(rows_iter[0])
            header = [f"column_{n}" for n in range(n_cols)]
        else:
            rows_iter = ws.iter_rows()
            for row in rows_iter:
                row_values = [cell.value for cell in row]
                if any(v is not None for v in row_values):
                    header.extend(row_values)
                    break

    dtype = String if no_inference else None
    series_data = []
    for name, column_data in zip(header, zip(*rows_iter, strict=False), strict=False):
        if name or not drop_empty_cols:

View on GitHub (pinned to fe841f959e)