{"record":{"id":"d5198b228c711e69","repo":"crewAIInc/crewAI","slug":"action-info-requires-path","errorCode":null,"errorMessage":"action='info' requires 'path'","messagePattern":"action='info' 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":284,"sourceCode":"                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:\n                    raise ValueError(\"action='move' requires 'path' and 'destination'\")\n                sandbox.fs.move_files(path, destination)\n                return {\"status\": \"moved\", \"from\": path, \"to\": destination}\n            if action == \"find\":\n                if path is None or pattern is None:\n                    raise ValueError(\"action='find' requires 'path' and 'pattern'\")\n                return self._find(sandbox, path, pattern)\n            if action == \"search\":\n                if path is None or pattern is None:\n                    raise ValueError(\"action='search' requires 'path' and 'pattern'\")\n                return self._search(sandbox, path, pattern)","sourceCodeStart":266,"sourceCodeEnd":302,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L266-L302","documentation":"For action='info' DaytonaFileTool._run needs a 'path' to fetch metadata for via self._info(sandbox, path). A missing path raises ValueError before any SDK call, so the error never reflects a sandbox-side problem. The info result (size, mode, timestamps) is only assembled after validation succeeds.","triggerScenarios":"Calling _run(action='info') with path omitted or explicitly None; agents that pass only the action verb; using 'file' or 'target' as the kwarg instead of 'path'.","commonSituations":"Agent-generated calls that assume the tool remembers a previously used path (the tool is stateless per call); exploratory calls while testing the tool with minimal arguments.","solutions":["Include the target: _run(action='info', path='/workspace/report.pdf').","Validate the kwargs against the tool schema before calling.","If chaining operations in an agent, require the path in every step of the plan, not just the first."],"exampleFix":"# before\ninfo = file_tool._run(action='info')\n\n# after\ninfo = file_tool._run(action='info', path='/workspace/report.pdf')","handlingStrategy":"validation","validationCode":"def safe_info(file_tool, path: str | None):\n    if not path:\n        raise ValueError(\"action='info' requires 'path'\")\n    return file_tool._run(action='info', path=path)","typeGuard":null,"tryCatchPattern":"try:\n    info = file_tool._run(action='info', path=path)\nexcept ValueError:\n    # path was None — re-ask the caller for the target\n    path = request_path_from_user_or_agent()","preventionTips":["Make path a required positional parameter of your own wrapper functions.","Log the full kwargs on failure so the missing key is obvious.","Never assume the tool remembers paths across calls — it is stateless."],"tags":["daytona","argument-validation","file-tool","metadata"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}