crewAIInc/crewAI · error · ValueError

action='find' requires 'pattern' (text to search for inside

Error message

action='find' requires 'pattern' (text to search for inside files).

What it means

DaytonaFileToolSchema._validate_action_args requires action='find' to carry a pattern, because 'find' means full-text search inside files and needs the text to look for. A missing/empty pattern fails validation with this ValueError.

Source

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

    )
    group: str | None = Field(
        default=None,
        description="For action='chmod': new file group.",
    )

    @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

View on GitHub (pinned to 754d7323be)

Solutions

  1. Pass the text to locate: tool.run(action='find', path='/workspace', pattern='TODO').
  2. If you want filename matching instead, use action='search' with a glob pattern such as '*.py'.
  3. Validate that the pattern string is non-empty before invoking the tool.

Example fix

# before
tool.run(action="find", path="/workspace")  # ValueError

# after
tool.run(action="find", path="/workspace", pattern="def main")
Defensive patterns

Strategy: validation

Validate before calling

def validate_find(path: str | None, pattern: str | None) -> None:
    if not path:
        raise ValueError("find requires path (directory)")
    if not pattern:
        raise ValueError("find requires pattern = text to search inside files")

validate_find(path, pattern)

Try / catch

try:
    tool.run(action="find", path=p, pattern=pat)
except ValidationError as e:
    if "requires 'pattern'" in str(e) and "text to search" in str(e):
        pat = default_search_text
        tool.run(action="find", path=p, pattern=pat)
    else:
        raise

Prevention

When it happens

Trigger: Calling DaytonaFileTool with action='find' and a path/directory but no pattern; confusing 'find' (grep-like content search) with 'search' (glob filename search) and passing the wrong kind of argument or none.

Common situations: Agent mixes up find (text inside files) and search (glob like '*.py'); caller assumes find lists files without criteria; pattern variable empty due to upstream escaping/quoting bug.

Related errors


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