crewAIInc/crewAI · error · ValueError

Directory must be provided.

Error message

Directory must be provided.

What it means

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.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/directory_read_tool/directory_read_tool.py:42

    )
    args_schema: type[BaseModel] = DirectoryReadToolSchema
    directory: str | None = None

    def __init__(self, directory: str | None = None, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        if directory is not None:
            self.directory = directory
            self.description = f"A tool that can be used to list {directory}'s content."
            self.args_schema = FixedDirectoryReadToolSchema
            self._generate_description()

    def _run(
        self,
        **kwargs: Any,
    ) -> Any:
        directory: str | None = kwargs.get("directory", self.directory)
        if directory is None:
            raise ValueError("Directory must be provided.")

        directory = validate_directory_path(directory)
        if directory[-1] == "/":
            directory = directory[:-1]
        files_list = [
            f"{directory}/{(os.path.join(root, filename).replace(directory, '').lstrip(os.path.sep))}"
            for root, dirs, files in os.walk(directory)
            for filename in files
        ]
        files = "\n- ".join(files_list)
        return f"File paths: \n-{files}"

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass directory explicitly: tool._run(directory='./src') — or set it at construction: DirectoryReadTool(directory='./src').
  2. Use the exact kwarg name 'directory'.
  3. Pre-check: if tool.directory is None, require the call argument.

Example fix

# before
tool = DirectoryReadTool()
result = tool._run()

# after
tool = DirectoryReadTool(directory='./src')
result = tool._run()  # or tool._run(directory='./src')
Defensive patterns

Strategy: validation

Validate before calling

def read_directory(tool: DirectoryReadTool, directory: str | None = None) -> str:
    directory = directory or tool.directory
    if not directory:
        raise ValueError('Directory must be provided.')
    return tool._run(directory=directory)

Type guard

def is_nonempty_directory_arg(value: object) -> bool:
    return isinstance(value, str) and bool(value.strip())

Try / catch

try:
    out = tool._run(**kwargs)
except ValueError as e:
    if 'Directory must be provided' in str(e):
        kwargs['directory'] = DEFAULT_WORKSPACE
        out = tool._run(**kwargs)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/6b5940d7b9f9f058. Report an issue: GitHub.