{"record":{"id":"561cc177f8643847","repo":"crewAIInc/crewAI","slug":"action-delete-requires-path","errorCode":null,"errorMessage":"action='delete' requires 'path'","messagePattern":"action='delete' requires 'path'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":273,"sourceCode":"            if action == \"read\":\n                if path is None:\n                    raise ValueError(\"action='read' requires 'path'\")\n                return self._read(sandbox, path, binary=binary)\n            if action == \"write\":\n                if path is None:\n                    raise ValueError(\"action='write' requires 'path'\")\n                return self._write(sandbox, path, content or \"\", binary=binary)\n            if action == \"append\":\n                if path is None:\n                    raise ValueError(\"action='append' requires 'path'\")\n                return self._append(sandbox, path, content or \"\", binary=binary)\n            if action == \"list\":\n                if path is None:\n                    raise ValueError(\"action='list' requires 'path'\")\n                return self._list(sandbox, path)\n            if action == \"delete\":\n                if path is None:\n                    raise ValueError(\"action='delete' requires 'path'\")\n                sandbox.fs.delete_file(path, recursive=recursive)\n                return {\"status\": \"deleted\", \"path\": path}\n            if action == \"mkdir\":\n                if path is None:\n                    raise ValueError(\"action='mkdir' requires 'path'\")\n                mkdir_mode = mode or \"0755\"\n                sandbox.fs.create_folder(path, mkdir_mode)\n                return {\"status\": \"created\", \"path\": path, \"mode\": mkdir_mode}\n            if action == \"info\":\n                if path is None:\n                    raise ValueError(\"action='info' requires 'path'\")\n                return self._info(sandbox, path)\n            if action == \"exists\":\n                if path is None:\n                    raise ValueError(\"action='exists' requires 'path'\")\n                return self._exists(sandbox, path)\n            if action == \"move\":\n                if path is None or destination is None:","sourceCodeStart":255,"sourceCodeEnd":291,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L255-L291","documentation":"DaytonaFileTool._run dispatches on an 'action' string and every action requires certain arguments. For action='delete' the tool requires a 'path' argument naming the sandbox file or folder to remove; when path is None it raises ValueError before touching the sandbox. This is a client-side argument validation error, not a Daytona SDK failure. The sandbox is released cleanly in the finally block, so no resources leak.","triggerScenarios":"Calling DaytonaFileTool._run(action='delete') without a path kwarg, or with path=None (e.g. an LLM agent emitting only {\"action\": \"delete\"}). Also passing the target under a different key such as 'file', 'target', or 'destination'.","commonSituations":"LLM-driven agents that format the tool call from natural language and omit the path; refactors that renamed the argument; copy-pasting an example for a different action (delete uses path, not destination).","solutions":["Pass a non-None path, e.g. _run(action='delete', path='/tmp/old.log', recursive=True).","Check the tool's args_schema (Daytona File Tool schema) for required kwargs per action before invoking.","If an agent is generating the call, add an explicit instruction in the tool description that every action except 'create' requires 'path'.","Pre-validate the kwargs dict in your own wrapper before calling the tool."],"exampleFix":"# before\nresult = file_tool._run(action='delete')\n\n# after\nresult = file_tool._run(action='delete', path='/workspace/staging/out.txt')","handlingStrategy":"validation","validationCode":"def validate_file_tool_kwargs(action: str, kwargs: dict) -> None:\n    required = {\n        'delete': ['path'], 'mkdir': ['path'], 'info': ['path'],\n        'exists': ['path'], 'move': ['path', 'destination'],\n        'chmod': ['path'],\n    }\n    for key in required.get(action, []):\n        if kwargs.get(key) is None:\n            raise ValueError(f\"action='{action}' requires '{key}'\")","typeGuard":null,"tryCatchPattern":"try:\n    result = file_tool._run(**kwargs)\nexcept ValueError as e:\n    if 'requires' in str(e):\n        log_and_repair_agent_call(str(e), kwargs)  # ask caller/agent to supply missing args\n    else:\n        raise","preventionTips":["Build tool calls from the tool's args_schema rather than hand-written dicts.","Keep an allowlist of required-argument sets per action and check before invoking.","In agent prompts, state that every Daytona action except 'create' requires 'path'."],"tags":["daytona","argument-validation","file-tool","valueerror"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}