crewAIInc/crewAI · error · FileNotFoundError
PDF file not found: {file_path}
Error message
PDF file not found: {file_path} What it means
Raised by PDFLoader.load() when a local (non-URL) source path is not an existing regular file — os.path.isfile fails. This is the local-file counterpart of the download error: before pymupdf opens the path, the loader verifies it exists; directories, dangling symlinks, and missing files all fail here with FileNotFoundError.
Source
Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/pdf_loader.py:112
source_name = Path(urlparse(file_path).path).name or "downloaded.pdf"
else:
source_name = Path(file_path).name
text_content: list[str] = []
metadata: dict[str, Any] = {
"source": file_path,
"file_name": source_name,
"file_type": "pdf",
}
try:
if is_url:
doc = pymupdf.open(
stream=self._fetch_from_url(file_path, kwargs), filetype="pdf"
)
else:
if not os.path.isfile(file_path):
raise FileNotFoundError(f"PDF file not found: {file_path}")
doc = pymupdf.open(file_path)
# Closed in a finally so a failure mid-extraction still releases the
# document handle.
try:
metadata["num_pages"] = len(doc)
for page_num, page in enumerate(doc, 1):
page_text = page.get_text()
if page_text.strip():
text_content.append(f"Page {page_num}:\n{page_text}")
finally:
doc.close()
except FileNotFoundError:
raise
except Exception as e:
raise ValueError(f"Error reading PDF from {file_path}: {e!s}") from e
View on GitHub (pinned to 754d7323be)
Solutions
- Check existence first: Path(src).expanduser().resolve().is_file() and fail with your own context.
- Use absolute paths anchored to a known base instead of cwd-relative strings.
- If the file is produced asynchronously, wait for a completion marker (e.g. .part suffix removed) before loading.
Example fix
# before
result = PDFLoader().load(SourceContent('downloads/report.pdf')) # cwd mismatch
# after
from pathlib import Path
pdf = Path('downloads/report.pdf').resolve()
assert pdf.is_file(), f'missing PDF: {pdf}'
result = PDFLoader().load(SourceContent(str(pdf))) Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path\n\ndef assert_pdf_file(path: str) -> None:\n p = Path(path).expanduser().resolve()\n if not p.is_file():\n raise FileNotFoundError(f'PDF file not found: {p}') Type guard
from pathlib import Path\n\ndef is_pdf_file(s: str) -> bool:\n return s.startswith(('http://', 'https://')) or (Path(s).expanduser().is_file() and s.lower().endswith('.pdf')) Try / catch
try:\n result = PDFLoader().load(source)\nexcept FileNotFoundError:\n logger.warning('missing PDF skipped: %s', source.source)\n result = None Prevention
- Anchor PDF paths to absolute locations resolved from config.
- Verify Docker volume mounts before batch ingestion.
- Only load files after their writer signals completion (no .part suffix).
When it happens
Trigger: PDFLoader().load(SourceContent('/data/missing.pdf')) where the file was never created, was deleted, lives in an unmounted volume, or the relative path resolves against the wrong cwd; also when a directory path is passed instead of a .pdf file.
Common situations: Docker deployments without the volume mounted at the expected path; notebooks where cwd differs from the project root; race conditions where the PDF is still being written/downloaded when load is called; typos or unexpanded ~ in configured paths.
Related errors
- Directory does not exist: {source_ref}
- Path is not a directory: {source_ref}
- Source must be a valid file path or URL, got: {source_conten
- File not found: {self.path}
- Path is not a file: {self.path}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/3434087008d535fe.
Report an issue: GitHub.