crewAIInc/crewAI · error · FileNotFoundError
The following file does not exist: {source_content.source}
Error message
The following file does not exist: {source_content.source} What it means
A plain FileNotFoundError raised by TextFileLoader.load when source_content.path_exists() returns False. It is the standard Python missing-file signal (not a ValueError), so existing except FileNotFoundError handling works. The message echoes source_content.source verbatim.
Source
Thrown at lib/crewai-tools/src/crewai_tools/rag/loaders/text_loader.py:11
from typing import Any
from crewai_tools.rag.base_loader import BaseLoader, LoaderResult
from crewai_tools.rag.source_content import SourceContent
class TextFileLoader(BaseLoader):
def load(self, source_content: SourceContent, **kwargs: Any) -> LoaderResult: # type: ignore[override]
source_ref = source_content.source_ref
if not source_content.path_exists():
raise FileNotFoundError(
f"The following file does not exist: {source_content.source}"
)
with open(source_content.source, encoding="utf-8") as file:
content = file.read()
return LoaderResult(
content=content,
source=source_ref,
doc_id=self.generate_doc_id(source_ref=source_ref, content=content),
)
class TextLoader(BaseLoader):
def load(self, source_content: SourceContent, **kwargs: Any) -> LoaderResult: # type: ignore[override]
return LoaderResult(
content=source_content.source,
source=source_content.source_ref,View on GitHub (pinned to 754d7323be)
Solutions
- Check the path exists and resolve it to absolute before loading: os.path.isfile(os.path.abspath(path)).
- If the path is relative, anchor it to a known base directory instead of relying on cwd.
- Print repr(path) to expose trailing spaces, unicode look-alikes, or wrong case.
- When the source string comes from LLM output, validate it against a whitelist directory first.
Example fix
# before
result = loader.load(SourceContent(path="notes.txt")) # cwd-dependent
# after
import os
base = "/srv/data"
full = os.path.realpath(os.path.join(base, "notes.txt"))
if not os.path.isfile(full):
raise SystemExit(f"missing file: {full}")
result = loader.load(SourceContent(path=full)) Defensive patterns
Strategy: validation
Validate before calling
import os
def resolve_input_file(path: str, base: str) -> str:
full = os.path.realpath(os.path.join(base, path))
if not os.path.isfile(full):
raise FileNotFoundError(f"no such file: {full!r}")
return full Try / catch
try:
result = text_loader.load(src)
except FileNotFoundError as e:
log.info("skipping missing file: %s", src.source) Prevention
- Anchor relative paths to an explicit base directory, never cwd.
- Use repr(path) in logs to expose whitespace and unicode issues.
- Validate LLM-supplied filenames against an allowlisted directory before loading.
When it happens
Trigger: Calling text_loader.load(SourceContent(path='data/notes.txt')) when the file is absent, when the path is relative and the process cwd differs from what you assumed, or when the filename has trailing whitespace/invisible characters. Note the existence check uses path_exists() but open() uses source_content.source — a mismatched or URL-derived source can also reach open() with an invalid path and raise the OS-level FileNotFoundError instead.
Common situations: Running an agent from a different working directory than the shell where the path worked; paths passed by an LLM tool call that hallucinates filenames; case-sensitivity differences between macOS and Linux; files not committed/synced to the deployment environment.
Related errors
- File does not exist: {source_ref}
- Directory does not exist: {source_ref}
- Directory does not exist: {source_ref}
- Path is not a directory: {source_ref}
- Error reading PDF from {file_path}: {e!s}
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/779433ac286c2056.
Report an issue: GitHub.