crewAIInc/crewAI · error · ValueError
action='read' requires 'path'
Error message
action='read' requires 'path'
What it means
Inside DaytonaFileTool._run, each action re-checks its required argument defensively. For action='read' a None path raises ValueError("action='read' requires 'path'"). Under normal use the Pydantic schema validator already rejects a missing path, so this branch is only reachable when _run is invoked directly (bypassing schema validation), e.g. in tests or custom wiring.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:257
self,
action: FileAction,
path: str | None = None,
content: str | None = None,
binary: bool = False,
recursive: bool = False,
mode: str | None = None,
destination: str | None = None,
pattern: str | None = None,
replacement: str | None = None,
paths: list[str] | None = None,
owner: str | None = None,
group: str | None = None,
) -> Any:
sandbox, should_delete = self._acquire_sandbox()
try:
if action == "read":
if path is None:
raise ValueError("action='read' requires 'path'")
return self._read(sandbox, path, binary=binary)
if action == "write":
if path is None:
raise ValueError("action='write' requires 'path'")
return self._write(sandbox, path, content or "", binary=binary)
if action == "append":
if path is None:
raise ValueError("action='append' requires 'path'")
return self._append(sandbox, path, content or "", binary=binary)
if action == "list":
if path is None:
raise ValueError("action='list' requires 'path'")
return self._list(sandbox, path)
if action == "delete":
if path is None:
raise ValueError("action='delete' requires 'path'")
sandbox.fs.delete_file(path, recursive=recursive)
return {"status": "deleted", "path": path}View on GitHub (pinned to 754d7323be)
Solutions
- Invoke the tool through its public API (tool.run / BaseToolInputModel-validated path) so the schema catches bad input first.
- If calling _run directly, always pass a concrete path: tool._run(action='read', path='/workspace/file.txt').
- In tests, build arguments via the schema: DaytonaFileToolSchema(action='read', path=...).model_dump().
Example fix
# before tool._run(action="read", path=None) # ValueError # after tool.run(action="read", path="/workspace/main.py")
Defensive patterns
Strategy: validation
Validate before calling
def validated_read_call(tool, path: str | None) -> Any:
if path is None:
raise ValueError("action='read' requires an explicit path")
return tool.run(action="read", path=path) # schema-validated invocation Try / catch
try:
data = tool.run(action="read", path=p)
except ValueError as e:
if "requires 'path'" in str(e):
p = resolve_default_file()
data = tool.run(action="read", path=p)
else:
raise Prevention
- Never call _run directly; use run() so Pydantic validation runs first.
- Default missing paths at your call site instead of passing None.
- Cover the read action in integration tests with both valid and missing paths.
When it happens
Trigger: Calling tool._run(action='read', path=None, ...) directly instead of tool.run(...) / validated invocation; subclass or test harness that constructs arguments programmatically and skips the Pydantic model_validator.
Common situations: Unit tests exercising _run directly; custom tool wrappers calling the private method; monkeypatched paths where the schema step is skipped.
Related errors
- action='write' requires 'path'
- action='append' requires 'path'
- action='list' requires 'path'
- action={self.action!r} requires 'path'.
- action='append' requires 'content'. Pass the chunk to append
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/185a34e2e1f2bf2c.
Report an issue: GitHub.