{"record":{"id":"1b8afd3105745981","repo":"crewAIInc/crewAI","slug":"action-find-requires-path-and-pattern","errorCode":null,"errorMessage":"action='find' requires 'path' and 'pattern'","messagePattern":"action='find' requires 'path' and 'pattern'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":297,"sourceCode":"                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)\n            if action == \"chmod\":\n                if path is None:\n                    raise ValueError(\"action='chmod' requires 'path'\")\n                return self._chmod(sandbox, path, mode=mode, owner=owner, group=group)\n            if action == \"replace\":\n                if paths is None or pattern is None or replacement is None:\n                    raise ValueError(\n                        \"action='replace' requires 'paths', 'pattern', and \"\n                        \"'replacement'\"\n                    )\n                return self._replace(sandbox, paths, pattern, replacement)\n            raise ValueError(f\"Unknown action: {action}\")\n        finally:","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L279-L315","documentation":"action='find' in DaytonaFileTool._run requires 'path' (search root) and 'pattern' (glob), and raises ValueError if either is None before delegating to self._find. Both arguments are checked together with one condition. No sandbox I/O happens when the check fails.","triggerScenarios":"Calling _run(action='find', path='/workspace') with no pattern, or _run(action='find', pattern='*.py') with no root; agents that say 'find python files' and omit the directory.","commonSituations":"Agents assuming a default root (e.g. current directory); users confusing pattern (glob for filenames) with the search action's pattern (file content regex); partial JSON tool calls.","solutions":["Pass both: _run(action='find', path='/workspace', pattern='**/*.log').","Pre-check kwargs: if action == 'find', require path and pattern keys.","In agent prompts, require an explicit search root and glob for every find step."],"exampleFix":"# before\nfile_tool._run(action='find', pattern='*.log')\n\n# after\nfile_tool._run(action='find', path='/var/log', pattern='**/*.log')","handlingStrategy":"validation","validationCode":"def find_files(file_tool, root: str | None, pattern: str | None):\n    if not root or not pattern:\n        raise ValueError(\"action='find' requires 'path' and 'pattern'\")\n    return file_tool._run(action='find', path=root, pattern=pattern)","typeGuard":null,"tryCatchPattern":"try:\n    res = file_tool._run(action='find', path=root, pattern=pattern)\nexcept ValueError as e:\n    if 'find' in str(e):\n        pattern = pattern or '**/*'  # safe default, retry once\n        res = file_tool._run(action='find', path=root, pattern=pattern)\n    else:\n        raise","preventionTips":["Default the pattern to '**/*' in your wrapper when the caller only gives a root.","Validate agent tool JSON with pydantic before execution.","Document the difference between find (glob) and search (content) in prompts."],"tags":["daytona","argument-validation","file-tool","find","glob"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}