binary-husky/gpt_academic · error · ValueError

File not found: {path}

Error message

File not found: {path}

What it means

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.

Source

Thrown at crazy_functions/doc_fns/read_fns/excel_reader.py:73

    def _detect_encoding(self, file_path: Path) -> str:
        if self.config.encoding != 'auto':
            return self.config.encoding

        try:
            with open(file_path, 'rb') as f:
                raw_data = f.read(10000)
                result = chardet.detect(raw_data)
                return result['encoding'] or 'utf-8'
        except Exception as e:
            self.logger.warning(f"Encoding detection failed: {e}. Using utf-8")
            return 'utf-8'

    def _validate_file(self, file_path: Union[str, Path]) -> Path:
        path = Path(file_path).resolve()

        if not path.exists():
            raise ValueError(f"File not found: {path}")

        if not path.is_file():
            raise ValueError(f"Not a file: {path}")

        if not os.access(path, os.R_OK):
            raise PermissionError(f"No read permission: {path}")

        if path.suffix.lower() not in self.SUPPORTED_EXTENSIONS:
            raise ValueError(
                f"Unsupported format: {path.suffix}. "
                f"Supported: {', '.join(sorted(self.SUPPORTED_EXTENSIONS))}"
            )

        return path

    def _format_value(self, value: Any) -> str:
        if pd.isna(value) or value is None:
            return ''

View on GitHub (pinned to d6bde0fa54)

Solutions

  1. Compare the absolute path in the message against where the file actually is; use Path(...).resolve() or os.path.abspath before calling
  2. If the path comes from user input, validate existence early and return a friendly error
  3. For uploads, ensure the temp file outlives the extraction call (close/move before parse)
  4. Normalize separators for cross-platform inputs

Example fix

// before
extractor.read_text('uploads/report.xlsx')  # run from wrong CWD -> File not found

// after
fp = Path('uploads/report.xlsx').resolve()
extractor.read_text(fp)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

fp = Path(user_input).expanduser().resolve()
if not fp.exists():
    raise ValueError(f'no such file: {fp}')  # fail before the extractor does

Type guard

from pathlib import Path

def is_readable_file(v) -> bool:
    p = Path(v)
    return p.exists() and p.is_file()

Try / catch

try:
    text = extractor.read_text(fp)
except ValueError as e:
    if str(e).startswith('File not found'):
        return friendly_error(f'{fp} 不存在,请重新上传')
    raise

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of binary-husky/gpt_academic@d6bde0fa54 (2026-08-14). Data as JSON: /api/errors/62dc7df2b36a9b5e. Report an issue: GitHub.