crewAIInc/crewAI · error · ValueError

Unknown action: {action}

Error message

Unknown action: {action}

What it means

Raised by E2BFileTool._run when the 'action' string does not match any of the handled cases (read, write, append, list, delete, mkdir, info, exists). It is the final else-branch after the if/elif chain over known actions, so any typo'd or unsupported action name reaches it.

Source

Thrown at lib/crewai-tools/src/crewai_tools/tools/e2b_sandbox_tool/e2b_file_tool.py:117

            if action == "read":
                return self._read(sandbox, path, binary=binary)
            if action == "write":
                return self._write(sandbox, path, content or "", binary=binary)
            if action == "append":
                return self._append(sandbox, path, content or "", binary=binary)
            if action == "list":
                return self._list(sandbox, path, depth=depth)
            if action == "delete":
                sandbox.files.remove(path)
                return {"status": "deleted", "path": path}
            if action == "mkdir":
                created = sandbox.files.make_dir(path)
                return {"status": "created", "path": path, "created": bool(created)}
            if action == "info":
                return self._info(sandbox, path)
            if action == "exists":
                return {"path": path, "exists": bool(sandbox.files.exists(path))}
            raise ValueError(f"Unknown action: {action}")
        finally:
            self._release_sandbox(sandbox, should_kill)

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

View on GitHub (pinned to 754d7323be)

Solutions

  1. Use one of the supported actions exactly: 'read', 'write', 'append', 'list', 'delete', 'mkdir', 'info', 'exists' (check the schema description for the canonical list).
  2. If you need 'remove', the supported equivalent is action='delete'.
  3. Validate the action string in your own code before invoking the tool (see defense below).

Example fix

# before
tool._run(action='remove', path='/tmp/x.txt')

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

Strategy: validation

Validate before calling

E2B_FILE_ACTIONS = {'read','write','append','list','delete','mkdir','info','exists'}
assert action in E2B_FILE_ACTIONS, f'action must be one of {sorted(E2B_FILE_ACTIONS)}'

Type guard

def is_e2b_file_action(a: str) -> bool:
    return a in {'read','write','append','list','delete','mkdir','info','exists'}

Try / catch

try:
    result = tool._run(action=action, path=path)
except ValueError as e:
    if 'Unknown action' in str(e):
        action = 'delete' if action == 'remove' else action  # map or re-raise
    else:
        raise

Prevention

When it happens

Trigger: Passing action='remove' or action='copy' (not supported), a typo like action='lst' or 'Write', or a differently-cased action such as 'READ' — matching is case-sensitive exact string comparison.

Common situations: An LLM agent invents an action not in the tool's description; callers upgraded from an older version where action names differed; locale/case confusion in generated tool args.

Related errors


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