pola-rs/polars · error · ValueError

cannot specify both `sheet_name

Error message

cannot specify both `sheet_name` ({sheet_name!r}) and `sheet_id` ({sheet_id!r})

What it means

`read_excel` allows selecting sheets either by index (`sheet_id`) or by name (`sheet_name`), but not both at once, since the selections could disagree. `_get_sheet_names` raises a `ValueError` when both are non-None.

Solutions

  1. Pass only `sheet_id` OR only `sheet_name`
  2. Set one of them explicitly to None
  3. If multiple selections are needed, pass a list to a single parameter (both accept lists)

Example fix

// before
pl.read_excel(f, sheet_id=1, sheet_name='Sales')
// after
pl.read_excel(f, sheet_name='Sales')
Defensive patterns

Strategy: validation

Validate before calling

assert sheet_id is None or sheet_name is None, 'pass sheet_id or sheet_name, not both'

Try / catch

try:
    df = pl.read_excel(f, sheet_id=sid, sheet_name=sname)
except ValueError as e:
    if 'cannot specify both' in str(e):
        df = pl.read_excel(f, sheet_name=sname)
    else:
        raise

Prevention

When it happens

Trigger: `pl.read_excel(f, sheet_id=1, sheet_name='Sales')` or passing a non-default value for both parameters in any combination (ints, strings, or lists).

Common situations: Combining defaults from a wrapper function where each parameter defaults to a sentinel that became non-None; copy-pasted calls that accumulate parameters.

Related errors


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

Appendix: source

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

        if "has_header" not in read_options:
            read_options["has_header"] = has_header
    else:
        read_options["infer_schema_length"] = infer_schema_length
        read_options["has_header"] = has_header

    return read_options


def _get_sheet_names(
    sheet_id: int | Sequence[int] | None,
    sheet_name: str | Sequence[str] | None,
    table_name: str | None,
    worksheets: list[dict[str, Any]],
) -> tuple[list[str], bool]:
    """Establish sheets to read; indicate if we are returning a dict frames."""
    if sheet_id is not None and sheet_name is not None:
        msg = f"cannot specify both `sheet_name` ({sheet_name!r}) and `sheet_id` ({sheet_id!r})"
        raise ValueError(msg)

    sheet_names = []
    if sheet_id is None and sheet_name is None:
        name = None if table_name else worksheets[0]["name"]
        sheet_names.append(name)
        return_multiple_sheets = False
    elif sheet_id == 0:
        sheet_names.extend(ws["name"] for ws in worksheets)
        return_multiple_sheets = True
    else:
        return_multiple_sheets = (
            (isinstance(sheet_name, Sequence) and not isinstance(sheet_name, str))
            or isinstance(sheet_id, Sequence)
            or sheet_id == 0
        )
        if names := (
            (sheet_name,) if isinstance(sheet_name, str) else sheet_name or ()
        ):

View on GitHub (pinned to fe841f959e)