crewAIInc/crewAI · error · ValueError

Unknown action: {action}

Error message

Unknown action: {action}

What it means

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.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:314

                if path is None or pattern is None:
                    raise ValueError("action='find' requires 'path' and 'pattern'")
                return self._find(sandbox, path, pattern)
            if action == "search":
                if path is None or pattern is None:
                    raise ValueError("action='search' requires 'path' and 'pattern'")
                return self._search(sandbox, path, pattern)
            if action == "chmod":
                if path is None:
                    raise ValueError("action='chmod' requires 'path'")
                return self._chmod(sandbox, path, mode=mode, owner=owner, group=group)
            if action == "replace":
                if paths is None or pattern is None or replacement is None:
                    raise ValueError(
                        "action='replace' requires 'paths', 'pattern', and "
                        "'replacement'"
                    )
                return self._replace(sandbox, paths, pattern, replacement)
            raise ValueError(f"Unknown action: {action}")
        finally:
            self._release_sandbox(sandbox, should_delete)

    def _read(self, sandbox: Any, path: str, *, binary: bool) -> dict[str, Any]:
        data: bytes = sandbox.fs.download_file(path)
        if binary:
            return {
                "path": path,
                "encoding": "base64",
                "content": base64.b64encode(data).decode("ascii"),
            }
        try:
            return {"path": path, "encoding": "utf-8", "content": data.decode("utf-8")}
        except UnicodeDecodeError:
            return {
                "path": path,
                "encoding": "base64",
                "content": base64.b64encode(data).decode("ascii"),

View on GitHub (pinned to 754d7323be)

Solutions

  1. 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).
  2. Print the tool's args_schema or source dispatch to see the exact accepted values for your installed version.
  3. Guard the action value in a wrapper with an allowlist set before calling _run.
  4. Upgrade crewai-tools if the docs mention an action your version rejects.

Example fix

# before
file_tool._run(action='rm', path='/tmp/x')

# after
file_tool._run(action='delete', path='/tmp/x')
Defensive patterns

Strategy: validation

Validate before calling

ALLOWED_ACTIONS = {'create', 'read', 'write', 'append', 'list', 'delete', 'mkdir',
                  'info', 'exists', 'move', 'find', 'search', 'chmod', 'replace'}

def safe_run(file_tool, action: str, **kwargs):
    a = action.lower().strip()
    if a not in ALLOWED_ACTIONS:
        raise ValueError(f"Unknown action: {action}. Allowed: {sorted(ALLOWED_ACTIONS)}")
    return file_tool._run(action=a, **kwargs)

Type guard

def is_known_action(value: object) -> bool:
    return isinstance(value, str) and value.lower().strip() in ALLOWED_ACTIONS

Try / catch

try:
    result = file_tool._run(action=action, **kwargs)
except ValueError as e:
    if str(e).startswith('Unknown action'):
        action = ALIAS_MAP.get(action.lower(), action)  # e.g. rm->delete, mv->move
        result = file_tool._run(action=action, **kwargs)
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15). Data as JSON: /api/errors/1528c8c4a61194fa. Report an issue: GitHub.