crewAIInc/crewAI · error · ValueError
action='move' requires 'path' and 'destination'
Error message
action='move' requires 'path' and 'destination'
What it means
action='move' in DaytonaFileTool._run needs BOTH 'path' (source) and 'destination' (target); if either is None it raises ValueError before calling sandbox.fs.move_files. The asymmetry with other actions (which need only path) is enforced with a single combined check. This is a client-side validation failure only.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:292
sandbox.fs.delete_file(path, recursive=recursive)
return {"status": "deleted", "path": path}
if action == "mkdir":
if path is None:
raise ValueError("action='mkdir' requires 'path'")
mkdir_mode = mode or "0755"
sandbox.fs.create_folder(path, mkdir_mode)
return {"status": "created", "path": path, "mode": mkdir_mode}
if action == "info":
if path is None:
raise ValueError("action='info' requires 'path'")
return self._info(sandbox, path)
if action == "exists":
if path is None:
raise ValueError("action='exists' requires 'path'")
return self._exists(sandbox, path)
if action == "move":
if path is None or destination is None:
raise ValueError("action='move' requires 'path' and 'destination'")
sandbox.fs.move_files(path, destination)
return {"status": "moved", "from": path, "to": destination}
if action == "find":
if path is None or pattern is None:
raise ValueError("action='find' requires 'path' and 'pattern'")
return self._find(sandbox, path, pattern)
if action == "search":
if path is None or pattern is None:
raise ValueError("action='search' requires 'path' and 'pattern'")
return self._search(sandbox, path, pattern)
if action == "chmod":
if path is None:
raise ValueError("action='chmod' requires 'path'")
return self._chmod(sandbox, path, mode=mode, owner=owner, group=group)
if action == "replace":
if paths is None or pattern is None or replacement is None:
raise ValueError(
"action='replace' requires 'paths', 'pattern', and "View on GitHub (pinned to 754d7323be)
Solutions
- Supply both arguments: _run(action='move', path='/workspace/a.txt', destination='/archive/a.txt').
- Pre-validate: for action='move' require both keys present and non-None.
- Update the agent's tool instructions to state move takes exactly two required arguments.
Example fix
# before file_tool._run(action='move', path='/tmp/draft.md') # after file_tool._run(action='move', path='/tmp/draft.md', destination='/docs/final.md')
Defensive patterns
Strategy: validation
Validate before calling
def move_file(file_tool, path: str | None, destination: str | None):
if not path or not destination:
raise ValueError("action='move' requires both 'path' and 'destination'")
return file_tool._run(action='move', path=path, destination=destination) Try / catch
try:
file_tool._run(action='move', path=p, destination=d)
except ValueError as e:
if 'path' in str(e) and 'destination' in str(e):
d = d or default_archive_dir(p) # fill a sensible default and retry once
file_tool._run(action='move', path=p, destination=d)
else:
raise Prevention
- Model move as a two-field dataclass/TypedDict so both are enforced statically.
- Generate destination from path with an explicit function instead of relying on the agent.
- Assert both keys non-None in a pre-dispatch validator.
When it happens
Trigger: Calling _run(action='move', path='/a.txt') without destination, or _run(action='move', destination='/b.txt') without path; agents that rename by supplying only the new name.
Common situations: Agents treating move like rename (single argument); users assuming the tool infers the destination directory; kwargs sent as positionally ordered JSON that the schema does not accept.
Related errors
- action='delete' requires 'path'
- action='mkdir' requires 'path'
- action='info' requires 'path'
- action='exists' requires 'path'
- action='find' requires 'path' and 'pattern'
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/a9cd6e777fd450fe.
Report an issue: GitHub.