{"record":{"id":"779433ac286c2056","repo":"crewAIInc/crewAI","slug":"the-following-file-does-not-exist-source-content","errorCode":null,"errorMessage":"The following file does not exist: {source_content.source}","messagePattern":"The following file does not exist: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/text_loader.py","lineNumber":11,"sourceCode":"from typing import Any\n\nfrom crewai_tools.rag.base_loader import BaseLoader, LoaderResult\nfrom crewai_tools.rag.source_content import SourceContent\n\n\nclass TextFileLoader(BaseLoader):\n    def load(self, source_content: SourceContent, **kwargs: Any) -> LoaderResult:  # type: ignore[override]\n        source_ref = source_content.source_ref\n        if not source_content.path_exists():\n            raise FileNotFoundError(\n                f\"The following file does not exist: {source_content.source}\"\n            )\n\n        with open(source_content.source, encoding=\"utf-8\") as file:\n            content = file.read()\n\n        return LoaderResult(\n            content=content,\n            source=source_ref,\n            doc_id=self.generate_doc_id(source_ref=source_ref, content=content),\n        )\n\n\nclass TextLoader(BaseLoader):\n    def load(self, source_content: SourceContent, **kwargs: Any) -> LoaderResult:  # type: ignore[override]\n        return LoaderResult(\n            content=source_content.source,\n            source=source_content.source_ref,","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/text_loader.py#L1-L29","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nresult = loader.load(SourceContent(path=\"notes.txt\"))  # cwd-dependent\n\n# after\nimport os\nbase = \"/srv/data\"\nfull = os.path.realpath(os.path.join(base, \"notes.txt\"))\nif not os.path.isfile(full):\n    raise SystemExit(f\"missing file: {full}\")\nresult = loader.load(SourceContent(path=full))","handlingStrategy":"validation","validationCode":"import os\n\ndef resolve_input_file(path: str, base: str) -> str:\n    full = os.path.realpath(os.path.join(base, path))\n    if not os.path.isfile(full):\n        raise FileNotFoundError(f\"no such file: {full!r}\")\n    return full","typeGuard":null,"tryCatchPattern":"try:\n    result = text_loader.load(src)\nexcept FileNotFoundError as e:\n    log.info(\"skipping missing file: %s\", src.source)","preventionTips":["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."],"tags":["file-io","filesystem","rag","path"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}