{"record":{"id":"1528c8c4a61194fa","repo":"crewAIInc/crewAI","slug":"unknown-action-action","errorCode":null,"errorMessage":"Unknown action: {action}","messagePattern":"Unknown action: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":314,"sourceCode":"                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:\n            self._release_sandbox(sandbox, should_delete)\n\n    def _read(self, sandbox: Any, path: str, *, binary: bool) -> dict[str, Any]:\n        data: bytes = sandbox.fs.download_file(path)\n        if binary:\n            return {\n                \"path\": path,\n                \"encoding\": \"base64\",\n                \"content\": base64.b64encode(data).decode(\"ascii\"),\n            }\n        try:\n            return {\"path\": path, \"encoding\": \"utf-8\", \"content\": data.decode(\"utf-8\")}\n        except UnicodeDecodeError:\n            return {\n                \"path\": path,\n                \"encoding\": \"base64\",\n                \"content\": base64.b64encode(data).decode(\"ascii\"),","sourceCodeStart":296,"sourceCodeEnd":332,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L296-L332","documentation":"DaytonaFileTool._run ends its action dispatch chain with raise ValueError(f\"Unknown action: {action}\") — the action string did not match any of read/write/append/list/delete/mkdir/info/exists/move/find/search/chmod/replace. This fires only after every known action check has failed, so the action value is misspelled, differently cased, or unsupported. It is the tool's exhaustive fallback for a bad discriminator value.","triggerScenarios":"Calling _run(action='rm' or 'remove' or 'copy' or 'Write'); passing 'DELETE' (uppercase — matching is case-sensitive); a typo like 'deleet'; an agent inventing an action not in the schema.","commonSituations":"Agents mapping Unix command names (rm, mv, cp) to the tool instead of the tool's verbs; case mismatches; newer/older expectation mismatch where a action exists in docs but not in the installed version.","solutions":["Use one of the supported lowercase action strings: read, write, append, list, delete, mkdir, info, exists, move, find, search, chmod, replace (and create, handled earlier).","Print the tool's args_schema or source dispatch to see the exact accepted values for your installed version.","Guard the action value in a wrapper with an allowlist set before calling _run.","Upgrade crewai-tools if the docs mention an action your version rejects."],"exampleFix":"# before\nfile_tool._run(action='rm', path='/tmp/x')\n\n# after\nfile_tool._run(action='delete', path='/tmp/x')","handlingStrategy":"validation","validationCode":"ALLOWED_ACTIONS = {'create', 'read', 'write', 'append', 'list', 'delete', 'mkdir',\n                  'info', 'exists', 'move', 'find', 'search', 'chmod', 'replace'}\n\ndef safe_run(file_tool, action: str, **kwargs):\n    a = action.lower().strip()\n    if a not in ALLOWED_ACTIONS:\n        raise ValueError(f\"Unknown action: {action}. Allowed: {sorted(ALLOWED_ACTIONS)}\")\n    return file_tool._run(action=a, **kwargs)","typeGuard":"def is_known_action(value: object) -> bool:\n    return isinstance(value, str) and value.lower().strip() in ALLOWED_ACTIONS","tryCatchPattern":"try:\n    result = file_tool._run(action=action, **kwargs)\nexcept ValueError as e:\n    if str(e).startswith('Unknown action'):\n        action = ALIAS_MAP.get(action.lower(), action)  # e.g. rm->delete, mv->move\n        result = file_tool._run(action=action, **kwargs)\n    else:\n        raise","preventionTips":["Normalize agent-emitted verbs (rm->delete, mv->move, cat->read) with an alias map before dispatch.","Lowercase and strip the action string — matching is case- and whitespace-sensitive.","Print the args_schema when integrating to learn the exact accepted action set."],"tags":["daytona","argument-validation","file-tool","unknown-action","dispatch"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}