{"record":{"id":"d1d2c52053f8da6e","repo":"crewAIInc/crewAI","slug":"directory-does-not-exist-source-ref-d1d2c5","errorCode":null,"errorMessage":"Directory does not exist: {source_ref}","messagePattern":"Directory does not exist: (.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/rag/loaders/directory_loader.py","lineNumber":29,"sourceCode":"        \"\"\"Load and process all files from a directory recursively.\n\n        Args:\n            source_content: Directory path or URL to a directory listing\n            **kwargs: Additional options:\n                - recursive: bool (default True) - Whether to search recursively\n                - include_extensions: list - Only include files with these extensions\n                - exclude_extensions: list - Exclude files with these extensions\n                - max_files: int - Maximum number of files to process\n        \"\"\"\n        source_ref = source_content.source_ref\n\n        if source_content.is_url():\n            raise ValueError(\n                \"URL directory loading is not supported. Please provide a local directory path.\"\n            )\n\n        if not os.path.exists(source_ref):\n            raise FileNotFoundError(f\"Directory does not exist: {source_ref}\")\n\n        if not os.path.isdir(source_ref):\n            raise ValueError(f\"Path is not a directory: {source_ref}\")\n\n        return self._process_directory(source_ref, kwargs)\n\n    def _process_directory(self, dir_path: str, kwargs: dict[str, Any]) -> LoaderResult:\n        recursive: bool = kwargs.get(\"recursive\", True)\n        include_extensions: list[str] | None = kwargs.get(\"include_extensions\", None)\n        exclude_extensions: list[str] | None = kwargs.get(\"exclude_extensions\", None)\n        max_files: int | None = kwargs.get(\"max_files\", None)\n\n        files = self._find_files(\n            dir_path, recursive, include_extensions, exclude_extensions\n        )\n\n        if max_files is not None and len(files) > max_files:\n            files = files[:max_files]","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/rag/loaders/directory_loader.py#L11-L47","documentation":"Raised by DirectoryLoader.load() when the local directory path given to the loader does not exist on disk. The loader explicitly rejects URLs first, then checks os.path.exists(source_ref); a missing path raises FileNotFoundError before any file collection starts. It is a fail-fast guard so callers learn immediately that the source directory is wrong rather than getting an empty result.","triggerScenarios":"Calling DirectoryLoader().load(SourceContent('/path/that/does/not/exist')) or passing a directory string with a typo, a relative path resolved against the wrong working directory, or a path from config/env that is not mounted in the container.","commonSituations":"Running CrewAI tools inside Docker where the data directory is not volume-mounted; CI jobs where fixtures are generated after the loader runs; relative paths that work locally but break when the process cwd changes; paths built from environment variables that are unset in production.","solutions":["Verify the path exists before loading: os.path.isdir(path) or Path(path).resolve() to catch cwd-relative mistakes.","If containerized, mount the directory into the container and confirm the mount target matches the path passed to the loader.","Use absolute paths (Path(__file__).parent / 'data') instead of strings that depend on process cwd.","Check for typos, trailing whitespace, and shell-expansion artifacts (~ unexpanded, escaped spaces) in the configured path."],"exampleFix":"# before\nloader = DirectoryLoader()\nresult = loader.load(SourceContent('data/docs'))\n\n# after\nfrom pathlib import Path\np = Path('data/docs').resolve()\nif not p.is_dir():\n    raise FileNotFoundError(f'docs dir missing: {p}')\nresult = loader.load(SourceContent(str(p)))","handlingStrategy":"validation","validationCode":"import os\n\ndef assert_source_dir(path: str) -> None:\n    if not os.path.exists(path):\n        raise FileNotFoundError(f'Directory does not exist: {path}')\n    if not os.path.isdir(path):\n        raise NotADirectoryError(f'Not a directory: {path}')","typeGuard":null,"tryCatchPattern":"try:\\n    result = loader.load(source)\\nexcept FileNotFoundError:\\n    logger.warning('skipping missing dir: %s', source.source_ref)\\n    result = None","preventionTips":["Resolve paths to absolute form before constructing SourceContent.","In containers, verify mounts with a startup check before any load call.","Never trust raw config strings; expand user/env tokens first."],"tags":["filesystem","loader","rag","validation"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}