{"record":{"id":"6b5940d7b9f9f058","repo":"crewAIInc/crewAI","slug":"directory-must-be-provided","errorCode":null,"errorMessage":"Directory must be provided.","messagePattern":"Directory must be provided\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/directory_read_tool/directory_read_tool.py","lineNumber":42,"sourceCode":"    )\n    args_schema: type[BaseModel] = DirectoryReadToolSchema\n    directory: str | None = None\n\n    def __init__(self, directory: str | None = None, **kwargs: Any) -> None:\n        super().__init__(**kwargs)\n        if directory is not None:\n            self.directory = directory\n            self.description = f\"A tool that can be used to list {directory}'s content.\"\n            self.args_schema = FixedDirectoryReadToolSchema\n            self._generate_description()\n\n    def _run(\n        self,\n        **kwargs: Any,\n    ) -> Any:\n        directory: str | None = kwargs.get(\"directory\", self.directory)\n        if directory is None:\n            raise ValueError(\"Directory must be provided.\")\n\n        directory = validate_directory_path(directory)\n        if directory[-1] == \"/\":\n            directory = directory[:-1]\n        files_list = [\n            f\"{directory}/{(os.path.join(root, filename).replace(directory, '').lstrip(os.path.sep))}\"\n            for root, dirs, files in os.walk(directory)\n            for filename in files\n        ]\n        files = \"\\n- \".join(files_list)\n        return f\"File paths: \\n-{files}\"\n","sourceCodeStart":24,"sourceCodeEnd":54,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/directory_read_tool/directory_read_tool.py#L24-L54","documentation":"DirectoryReadTool._run resolves the directory from kwargs.get('directory', self.directory); if both the call argument and the constructor/instance value are None it raises ValueError('Directory must be provided.'). If a directory was set at construction the call may omit it, but with nothing set anywhere the tool cannot know what to walk. After this check the path is passed through validate_directory_path before os.walk.","triggerScenarios":"Instantiating DirectoryReadTool() with no directory and calling _run() with no kwargs; an LLM emitting {} or only unrelated fields; passing the location under a different key ('dir', 'path', 'folder') so kwargs.get misses it.","commonSituations":"Agents calling the tool with an empty arguments object; setting self.directory = None after construction; typos in the kwarg name so the default (None) wins.","solutions":["Pass directory explicitly: tool._run(directory='./src') — or set it at construction: DirectoryReadTool(directory='./src').","Use the exact kwarg name 'directory'.","Pre-check: if tool.directory is None, require the call argument."],"exampleFix":"# before\ntool = DirectoryReadTool()\nresult = tool._run()\n\n# after\ntool = DirectoryReadTool(directory='./src')\nresult = tool._run()  # or tool._run(directory='./src')","handlingStrategy":"validation","validationCode":"def read_directory(tool: DirectoryReadTool, directory: str | None = None) -> str:\n    directory = directory or tool.directory\n    if not directory:\n        raise ValueError('Directory must be provided.')\n    return tool._run(directory=directory)","typeGuard":"def is_nonempty_directory_arg(value: object) -> bool:\n    return isinstance(value, str) and bool(value.strip())","tryCatchPattern":"try:\n    out = tool._run(**kwargs)\nexcept ValueError as e:\n    if 'Directory must be provided' in str(e):\n        kwargs['directory'] = DEFAULT_WORKSPACE\n        out = tool._run(**kwargs)\n    else:\n        raise","preventionTips":["Set the directory at construction: DirectoryReadTool(directory='./src').","Use the exact kwarg name 'directory' (not dir/path/folder) in agent tool schemas.","Validate agent-emitted JSON: require a non-empty 'directory' string before dispatch."],"tags":["directory-read-tool","argument-validation","filesystem","valueerror"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}