pola-rs/polars · error · ValueError

no matching sheet found when `sheet_id` is

Error message

no matching sheet found when `sheet_id` is {idx}

What it means

When selecting sheets by `sheet_id` (1-based index), `_get_sheet_names` looks each id up among available worksheets and raises a `ValueError` if an id has no matching sheet (e.g. beyond the sheet count, or id=0 which is invalid here).

Solutions

  1. Use a valid 1-based id within the sheet count (check len of sheets first)
  2. Use `sheet_name` if positions are unstable
  3. Clamp/validate ids in a list before passing them

Example fix

// before
pl.read_excel(f, sheet_id=0)
// after
pl.read_excel(f, sheet_id=1)
Defensive patterns

Strategy: validation

Validate before calling

n_sheets = len(sheets)
assert all(1 <= i <= n_sheets for i in ids), f'sheet_id must be 1..{n_sheets}'

Try / catch

try:
    df = pl.read_excel(f, sheet_id=sid)
except ValueError as e:
    if 'no matching sheet found' in str(e):
        df = pl.read_excel(f, sheet_id=1)
    else:
        raise

Prevention

When it happens

Trigger: `pl.read_excel(f, sheet_id=5)` on a 3-sheet workbook; `sheet_id=[1, 4]` where 4 doesn't exist; `sheet_id=0`, which never matches a worksheet index.

Common situations: Hardcoded sheet positions after the workbook gained/lost sheets; assuming 0-based indexing when ids are 1-based; looping over a range larger than the sheet count.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

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

            (sheet_name,) if isinstance(sheet_name, str) else sheet_name or ()
        ):
            known_sheet_names = {ws["name"] for ws in worksheets}
            for name in names:
                if name not in known_sheet_names:
                    msg = f"no matching sheet found when `sheet_name` is {name!r}"
                    raise ValueError(msg)
                sheet_names.append(name)
        else:
            ids = (sheet_id,) if isinstance(sheet_id, int) else sheet_id or ()
            sheet_names_by_idx = {
                idx: ws["name"]
                for idx, ws in enumerate(worksheets, start=1)
                if (sheet_id == 0 or ws["index"] in ids or ws["name"] in names)
            }
            for idx in ids:
                if (name := sheet_names_by_idx.get(idx)) is None:
                    msg = f"no matching sheet found when `sheet_id` is {idx}"
                    raise ValueError(msg)
                sheet_names.append(name)

    return sheet_names, return_multiple_sheets  # type: ignore[return-value]


def _initialise_spreadsheet_parser(
    engine: str | None,
    source: str | IO[bytes] | bytes,
    engine_options: dict[str, Any],
) -> tuple[Callable[..., pl.DataFrame], Any, list[dict[str, Any]]]:
    """Instantiate the indicated spreadsheet parser and establish related properties."""
    if isinstance(source, str) and not Path(source).exists():
        raise FileNotFoundError(source)

    if engine == "xlsx2csv":  # default
        xlsx2csv = import_optional("xlsx2csv")

        # establish sensible defaults for unset options

View on GitHub (pinned to fe841f959e)