crewAIInc/crewAI · error · ValueError
action='search' requires 'pattern' (glob, e.g. '*.py').
Error message
action='search' requires 'pattern' (glob, e.g. '*.py').
What it means
DaytonaFileToolSchema._validate_action_args requires action='search' to carry a pattern, where 'search' means glob-style filename search (e.g. '*.py'). A missing or empty pattern raises this ValueError during input validation, before the sandbox filesystem is touched.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:201
)
@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.View on GitHub (pinned to 754d7323be)
Solutions
- Provide a glob: tool.run(action='search', path='/workspace', pattern='*.py').
- For content search, switch to action='find' with the literal text as pattern.
- Double-check the field name is exactly 'pattern'.
Example fix
# before tool.run(action="search", path="/workspace") # ValueError # after tool.run(action="search", path="/workspace", pattern="*.py")
Defensive patterns
Strategy: validation
Validate before calling
def validate_search(path: str | None, pattern: str | None) -> None:
if not path:
raise ValueError("search requires path (directory)")
if not pattern:
raise ValueError("search requires pattern = glob like '*.py'")
validate_search(path, pattern) Try / catch
try:
tool.run(action="search", path=p, pattern=pat)
except ValidationError as e:
if "glob" in str(e):
pat = "*" # or a more specific glob
tool.run(action="search", path=p, pattern=pat)
else:
raise Prevention
- Use action='search' only with glob patterns; use 'find' for text content.
- Sanity-check that pattern is a valid glob (non-empty, no NUL) before the call.
- Keep a one-line cheat sheet of Daytona file actions in your tool wrapper.
When it happens
Trigger: Calling DaytonaFileTool with action='search' and a directory path but no pattern; passing the search text in the wrong field; passing a glob into a different argument name.
Common situations: Agent confuses search (glob) with find (file contents); caller passes pattern as 'query' or 'glob'; empty pattern from a formatted string that evaluated to ''.
Related errors
- action='find' requires 'pattern' (text to search for inside
- action={self.action!r} requires 'path'.
- action='append' requires 'content'. Pass the chunk to append
- action='move' requires 'destination'.
- action='chmod' requires at least one of 'mode', 'owner', or
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/e761648463743e00.
Report an issue: GitHub.