crewAIInc/crewAI · error · ValueError

action='chmod' requires at least one of 'mode', 'owner', or

Error message

action='chmod' requires at least one of 'mode', 'owner', or 'group'.

What it means

DaytonaFileToolSchema._validate_action_args enforces that action='chmod' changes something: at least one of mode (permissions string like '0755'), owner, or group must be provided. With none set the validator raises ValueError, since a chmod that alters nothing is almost certainly a caller mistake.

Source

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

    @model_validator(mode="after")
    def _validate_action_args(self) -> DaytonaFileToolSchema:
        if self.action != "replace" and not self.path:
            raise ValueError(f"action={self.action!r} requires 'path'.")
        if self.action == "append" and self.content is None:
            raise ValueError(
                "action='append' requires 'content'. Pass the chunk to append "
                "in the 'content' field."
            )
        if self.action == "move" and not self.destination:
            raise ValueError("action='move' requires 'destination'.")
        if self.action == "find" and not self.pattern:
            raise ValueError(
                "action='find' requires 'pattern' (text to search for inside files)."
            )
        if self.action == "search" and not self.pattern:
            raise ValueError("action='search' requires 'pattern' (glob, e.g. '*.py').")
        if self.action == "chmod" and not (self.mode or self.owner or self.group):
            raise ValueError(
                "action='chmod' requires at least one of 'mode', 'owner', or 'group'."
            )
        if self.action == "replace":
            if not self.paths:
                raise ValueError(
                    "action='replace' requires 'paths' (list of file paths)."
                )
            if not self.pattern:
                raise ValueError("action='replace' requires 'pattern'.")
            if self.replacement is None:
                raise ValueError("action='replace' requires 'replacement'.")
        return self


class DaytonaFileTool(DaytonaBaseTool):
    """Read, write, and manage files inside a Daytona sandbox.

    Notes:

View on GitHub (pinned to 754d7323be)

Solutions

  1. Provide at least one change target: tool.run(action='chmod', path='/workspace/script.sh', mode='0755').
  2. To change ownership instead: pass owner='user' and/or group='group'.
  3. Verify field names: it is 'mode', 'owner', 'group' — not 'permissions'.

Example fix

# before
tool.run(action="chmod", path="/workspace/script.sh")  # ValueError

# after
tool.run(action="chmod", path="/workspace/script.sh", mode="0755")
Defensive patterns

Strategy: validation

Validate before calling

def validate_chmod(path: str | None, mode: str | None, owner: str | None, group: str | None) -> None:
    if not path:
        raise ValueError("chmod requires path")
    if not (mode or owner or group):
        raise ValueError("chmod requires mode and/or owner and/or group")

validate_chmod(path, mode, owner, group)

Try / catch

try:
    tool.run(action="chmod", path=p, mode=m)
except ValidationError as e:
    if "'mode', 'owner', or 'group'" in str(e):
        tool.run(action="chmod", path=p, mode="0644")
    else:
        raise

Prevention

When it happens

Trigger: Calling DaytonaFileTool with action='chmod' and only a path (no mode/owner/group); passing the permission into a misnamed field; intending 'mkdir with mode' (a different action) instead of chmod.

Common situations: Agent omits the permission argument; caller uses 'permissions' or 'perm' as the field name instead of 'mode'; confusion between action='mkdir' (accepts mode) and action='chmod'.

Related errors


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