crewAIInc/crewAI · error · ValueError
action='move' requires 'destination'.
Error message
action='move' requires 'destination'.
What it means
DaytonaFileToolSchema._validate_action_args enforces that action='move' includes a non-empty destination (the target path to move/rename to). Without it the validator raises ValueError before any sandbox operation starts.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:195
default=None,
description="For action='chmod': new file owner (user name).",
)
group: str | None = Field(
default=None,
description="For action='chmod': new file group.",
)
@model_validator(mode="after")
def _validate_action_args(self) -> DaytonaFileToolSchema:
if self.action != "replace" and not self.path:
raise ValueError(f"action={self.action!r} requires 'path'.")
if self.action == "append" and self.content is None:
raise ValueError(
"action='append' requires 'content'. Pass the chunk to append "
"in the 'content' field."
)
if self.action == "move" and not self.destination:
raise ValueError("action='move' requires 'destination'.")
if self.action == "find" and not self.pattern:
raise ValueError(
"action='find' requires 'pattern' (text to search for inside files)."
)
if self.action == "search" and not self.pattern:
raise ValueError("action='search' requires 'pattern' (glob, e.g. '*.py').")
if self.action == "chmod" and not (self.mode or self.owner or self.group):
raise ValueError(
"action='chmod' requires at least one of 'mode', 'owner', or 'group'."
)
if self.action == "replace":
if not self.paths:
raise ValueError(
"action='replace' requires 'paths' (list of file paths)."
)
if not self.pattern:
raise ValueError("action='replace' requires 'pattern'.")
if self.replacement is None:View on GitHub (pinned to 754d7323be)
Solutions
- Supply destination: tool.run(action='move', path='/workspace/old.txt', destination='/workspace/new.txt').
- If a destination variable is computed upstream, assert it is non-empty before the tool call.
- Update the agent prompt/tool description so 'move' always produces both source and target paths.
Example fix
# before tool.run(action="move", path="/workspace/old.txt") # ValueError # after tool.run(action="move", path="/workspace/old.txt", destination="/workspace/new.txt")
Defensive patterns
Strategy: validation
Validate before calling
def validate_move(path: str | None, destination: str | None) -> None:
if not path or not destination:
raise ValueError("move requires both source 'path' and 'destination'")
validate_move(path, destination) Try / catch
try:
tool.run(action="move", path=p, destination=d)
except ValidationError as e:
if "requires 'destination'" in str(e):
d = derive_destination(p)
tool.run(action="move", path=p, destination=d)
else:
raise Prevention
- Compute and assert the destination path before issuing a move.
- In agent prompts, show a two-argument move example.
- Prefer full absolute paths for both source and target to avoid ambiguity.
When it happens
Trigger: Calling DaytonaFileTool with action='move' and path set but destination omitted or empty; an agent tool call that includes the source but forgets the target.
Common situations: LLM emits partial move arguments; caller assumes rename-in-place without destination; destination variable evaluates to '' because the target path was never computed.
Related errors
- action={self.action!r} requires 'path'.
- action='append' requires 'content'. Pass the chunk to append
- action='replace' requires 'paths' (list of file paths).
- action='replace' requires 'pattern'.
- action='replace' requires 'replacement'.
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/98f8ffc224b21a50.
Report an issue: GitHub.