{"record":{"id":"98f8ffc224b21a50","repo":"crewAIInc/crewAI","slug":"action-move-requires-destination","errorCode":null,"errorMessage":"action='move' requires 'destination'.","messagePattern":"action='move' requires 'destination'\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":195,"sourceCode":"        default=None,\n        description=\"For action='chmod': new file owner (user name).\",\n    )\n    group: str | None = Field(\n        default=None,\n        description=\"For action='chmod': new file group.\",\n    )\n\n    @model_validator(mode=\"after\")\n    def _validate_action_args(self) -> DaytonaFileToolSchema:\n        if self.action != \"replace\" and not self.path:\n            raise ValueError(f\"action={self.action!r} requires 'path'.\")\n        if self.action == \"append\" and self.content is None:\n            raise ValueError(\n                \"action='append' requires 'content'. Pass the chunk to append \"\n                \"in the 'content' field.\"\n            )\n        if self.action == \"move\" and not self.destination:\n            raise ValueError(\"action='move' requires 'destination'.\")\n        if self.action == \"find\" and not self.pattern:\n            raise ValueError(\n                \"action='find' requires 'pattern' (text to search for inside files).\"\n            )\n        if self.action == \"search\" and not self.pattern:\n            raise ValueError(\"action='search' requires 'pattern' (glob, e.g. '*.py').\")\n        if self.action == \"chmod\" and not (self.mode or self.owner or self.group):\n            raise ValueError(\n                \"action='chmod' requires at least one of 'mode', 'owner', or 'group'.\"\n            )\n        if self.action == \"replace\":\n            if not self.paths:\n                raise ValueError(\n                    \"action='replace' requires 'paths' (list of file paths).\"\n                )\n            if not self.pattern:\n                raise ValueError(\"action='replace' requires 'pattern'.\")\n            if self.replacement is None:","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L177-L213","documentation":"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.","triggerScenarios":"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.","commonSituations":"LLM emits partial move arguments; caller assumes rename-in-place without destination; destination variable evaluates to '' because the target path was never computed.","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."],"exampleFix":"# before\ntool.run(action=\"move\", path=\"/workspace/old.txt\")  # ValueError\n\n# after\ntool.run(action=\"move\", path=\"/workspace/old.txt\", destination=\"/workspace/new.txt\")","handlingStrategy":"validation","validationCode":"def validate_move(path: str | None, destination: str | None) -> None:\n    if not path or not destination:\n        raise ValueError(\"move requires both source 'path' and 'destination'\")\n\nvalidate_move(path, destination)","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(action=\"move\", path=p, destination=d)\nexcept ValidationError as e:\n    if \"requires 'destination'\" in str(e):\n        d = derive_destination(p)\n        tool.run(action=\"move\", path=p, destination=d)\n    else:\n        raise","preventionTips":["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."],"tags":["daytona","pydantic","validation","input-validation","filesystem"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}