pola-rs/polars · error · FileNotFoundError

{source}

Error message

{source}

What it means

Raised by pl.read_excel / pl.read_ods in _initialise_spreadsheet_parser as a plain builtin FileNotFoundError (message is just the path) when source is a str that does not exist on disk. The check runs before any engine is loaded, so no optional dependency error can mask it. Note the string is first normalized (e.g. ~ expansion) and URLs are fetched earlier, so this only concerns local filesystem paths.

Source

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

                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
        for option, value in {
            "exclude_hidden_sheets": False,
            "skip_empty_lines": False,
            "skip_hidden_rows": False,
            "floatformat": "%f",
        }.items():
            engine_options.setdefault(option, value)

        if isinstance(source, bytes):
            source = BytesIO(source)

        parser = xlsx2csv.Xlsx2csv(source, **engine_options)
        sheets = parser.workbook.sheets

View on GitHub (pinned to df599052da)

Solutions

  1. Resolve and verify the path first: Path(source).expanduser().resolve() and check .exists()
  2. Check your working directory (os.getcwd()) if the path is relative
  3. If the file should have been produced by an earlier step, verify that step succeeded before reading

Example fix

# before
pl.read_excel('data/report.xlsx')

# after
from pathlib import Path
path = Path('data/report.xlsx').expanduser().resolve()
if not path.exists():
    raise FileNotFoundError(f'missing input file: {path}')
pl.read_excel(path)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

path = Path(source).expanduser().resolve() if isinstance(source, str) else Path(source)
if not path.is_file():
    raise FileNotFoundError(f'input workbook not found: {path} (cwd={Path.cwd()})')
df = pl.read_excel(path)

Try / catch

try:
    df = pl.read_excel(src)
except FileNotFoundError:
    # plain builtin exception; polars' message is just the path
    log.error('workbook missing: %s', src)
    raise

Prevention

When it happens

Trigger: pl.read_excel('data/report.xlsx') when the relative path is wrong for the current working directory; a typo in the filename; a file that a previous pipeline step failed to write; paths read from config/env vars that are unset or stale.

Common situations: Scripts run from a different cwd than expected (cron, notebooks, Airflow workers), Windows/Unix path separator mixups, race conditions where the file is created after the read starts.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/d6725c73df878e66. Report an issue: GitHub.