{"record":{"id":"614f333b468ed92d","repo":"pola-rs/polars","slug":"no-workbook-found-at-path-src-r","errorCode":null,"errorMessage":"no workbook found at path {src!r}","messagePattern":"no workbook found at path (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/io/spreadsheet/functions.py","lineNumber":77,"sourceCode":"    read_multiple_workbooks = True\n    sources: list[Any] = []\n\n    if isinstance(source, memoryview):\n        source = source.tobytes()\n    if not isinstance(source, Sequence) or isinstance(source, (bytes, str)):\n        read_multiple_workbooks = False\n        source = [source]  # type: ignore[assignment]\n\n    for src in source:  # type: ignore[union-attr]\n        if isinstance(src, (str, os.PathLike)) and not Path(src).exists():\n            src = os.path.expanduser(str(src))  # noqa: PTH111\n            if looks_like_url(src):\n                sources.append(src)\n                continue\n            sources.extend(files := glob(src, recursive=True))  # noqa: PTH207\n            if not files:\n                msg = f\"no workbook found at path {src!r}\"\n                raise FileNotFoundError(msg)\n            read_multiple_workbooks = True\n        else:\n            if isinstance(src, os.PathLike):\n                src = str(src)\n            sources.append(src)\n\n    return sources, read_multiple_workbooks\n\n\ndef _standardize_duplicates(s: str) -> str:\n    \"\"\"Standardize columns with '_duplicated_n' names.\"\"\"\n    return re.sub(r\"_duplicated_(\\d+)\", repl=r\"\\1\", string=s)\n\n\ndef _unpack_read_results(\n    frames: list[pl.DataFrame] | list[dict[str, pl.DataFrame]],\n    *,\n    read_multiple_workbooks: bool,","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/io/spreadsheet/functions.py#L59-L95","documentation":"FileNotFoundError raised while normalizing read_excel sources. When a str/PathLike source does not exist as a literal path, polars expands '~' and treats it as a glob pattern (glob.glob(src, recursive=True)); if the pattern matches nothing, the file was neither a real path, a URL, nor a matching glob, so reading cannot proceed. Note this fire-once message names the expanded pattern.","triggerScenarios":"pl.read_excel('~/reports/data_2024_*.xlsx') matching nothing; pl.read_excel('data[1].xlsx') where the literal file exists but '[' makes it an invalid/empty glob character class; plain wrong paths.","commonSituations":"Filenames containing glob metacharacters ([, ], *, ?) — very common with bracketed indices or dates; running on a different OS where the path separator or expansion differs; typos or files not yet downloaded; passing Path objects to files created asynchronously.","solutions":["If the filename is literal, check it exists first and escape metacharacters: src = glob.escape('data[1].xlsx') or pass a resolved Path after verifying Path(src).exists().","If it should be a glob, verify the pattern and working directory: print(glob.glob(pattern, recursive=True)) before calling read_excel.","For URLs, ensure the string is recognized as such (full https://... form) so it is not glob-expanded.","Guard with if not Path(src).exists() and not glob.glob(src): raise a clearer error with the intended location."],"exampleFix":"# before\npl.read_excel('data[1].xlsx')  # file exists, but '[' breaks the glob fallback\n\n# after\nimport glob, pathlib\nsrc = 'data[1].xlsx'\nassert pathlib.Path(src).exists()\npl.read_excel(glob.escape(src) if any(c in src for c in '[]*?') else src)","handlingStrategy":"validation","validationCode":"import glob, os\nfrom pathlib import Path\n\ndef resolve_excel_source(src: str) -> str:\n    if Path(src).exists():\n        return src\n    expanded = os.path.expanduser(src)\n    if Path(expanded).exists():\n        return expanded\n    if glob.glob(expanded, recursive=True):\n        return expanded\n    raise FileNotFoundError(f'no workbook at {src!r} (exists={Path(src).exists()})')\n\npl.read_excel(resolve_excel_source(src))","typeGuard":null,"tryCatchPattern":"try:\n    df = pl.read_excel(src)\nexcept FileNotFoundError as e:\n    if 'no workbook found at path' in str(e):\n        raise ValueError(f'check path/glob {src!r}: cwd={os.getcwd()}') from e\n    raise","preventionTips":["Prefer pathlib.Path objects and assert Path(src).exists() for literal files.","Escape glob metacharacters in literal filenames: glob.escape(name).","Remember polars falls back to recursive globbing for non-existent str paths — verify patterns against cwd."],"tags":["excel","spreadsheet","read-excel","file-not-found","glob","path-handling"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}