{"record":{"id":"62dc7df2b36a9b5e","repo":"binary-husky/gpt_academic","slug":"file-not-found-path","errorCode":null,"errorMessage":"File not found: {path}","messagePattern":"File not found: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"crazy_functions/doc_fns/read_fns/excel_reader.py","lineNumber":73,"sourceCode":"\n    def _detect_encoding(self, file_path: Path) -> str:\n        if self.config.encoding != 'auto':\n            return self.config.encoding\n\n        try:\n            with open(file_path, 'rb') as f:\n                raw_data = f.read(10000)\n                result = chardet.detect(raw_data)\n                return result['encoding'] or 'utf-8'\n        except Exception as e:\n            self.logger.warning(f\"Encoding detection failed: {e}. Using utf-8\")\n            return 'utf-8'\n\n    def _validate_file(self, file_path: Union[str, Path]) -> Path:\n        path = Path(file_path).resolve()\n\n        if not path.exists():\n            raise ValueError(f\"File not found: {path}\")\n\n        if not path.is_file():\n            raise ValueError(f\"Not a file: {path}\")\n\n        if not os.access(path, os.R_OK):\n            raise PermissionError(f\"No read permission: {path}\")\n\n        if path.suffix.lower() not in self.SUPPORTED_EXTENSIONS:\n            raise ValueError(\n                f\"Unsupported format: {path.suffix}. \"\n                f\"Supported: {', '.join(sorted(self.SUPPORTED_EXTENSIONS))}\"\n            )\n\n        return path\n\n    def _format_value(self, value: Any) -> str:\n        if pd.isna(value) or value is None:\n            return ''","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/binary-husky/gpt_academic/blob/d6bde0fa54373309bd05823a49bda8da019d2c77/crazy_functions/doc_fns/read_fns/excel_reader.py#L55-L91","documentation":"First check in ExcelTextExtractor._validate_file: after resolving the path, if it does not exist on disk, ValueError('File not found: <abs path>') is raised. This is a standard precondition check before any parsing; the resolved absolute path in the message is the authoritative hint.","triggerScenarios":"Passing a relative path resolved against an unexpected CWD, a URL instead of a local path, a path with a typo or wrong extension-qualified name, or a file deleted between listing and reading (TOCTOU).","commonSituations":"Web-upload pipelines where the uploaded temp file was cleaned up; relative paths like 'data/x.xlsx' run from a different working directory; Windows-style backslashes on Linux.","solutions":["Compare the absolute path in the message against where the file actually is; use Path(...).resolve() or os.path.abspath before calling","If the path comes from user input, validate existence early and return a friendly error","For uploads, ensure the temp file outlives the extraction call (close/move before parse)","Normalize separators for cross-platform inputs"],"exampleFix":"// before\nextractor.read_text('uploads/report.xlsx')  # run from wrong CWD -> File not found\n\n// after\nfp = Path('uploads/report.xlsx').resolve()\nextractor.read_text(fp)","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\nfp = Path(user_input).expanduser().resolve()\nif not fp.exists():\n    raise ValueError(f'no such file: {fp}')  # fail before the extractor does","typeGuard":"from pathlib import Path\n\ndef is_readable_file(v) -> bool:\n    p = Path(v)\n    return p.exists() and p.is_file()","tryCatchPattern":"try:\n    text = extractor.read_text(fp)\nexcept ValueError as e:\n    if str(e).startswith('File not found'):\n        return friendly_error(f'{fp} 不存在，请重新上传')\n    raise","preventionTips":["Resolve paths to absolute at the boundary of your app before passing them down","For uploads, keep temp files alive until parsing finishes","Validate existence early in request handling, not deep in the extractor"],"tags":["file-validation","path-handling","excel","python"],"backgroundTag":null,"analyzedSha":"d6bde0fa54373309bd05823a49bda8da019d2c77","analyzedAt":"2026-08-14T22:48:35.038Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}