crewAIInc/crewAI · error · ValueError
action='replace' requires 'paths', 'pattern', and 'replaceme
Error message
action='replace' requires 'paths', 'pattern', and 'replacement'
What it means
action='replace' in DaytonaFileTool._run is a bulk find-and-replace and requires three arguments: 'paths' (a list of files), 'pattern', and 'replacement'. If any of the three is None it raises ValueError before calling self._replace. Note it takes 'paths' (plural list), unlike most other actions that take a single 'path'.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:309
if path is None or destination is None:
raise ValueError("action='move' requires 'path' and 'destination'")
sandbox.fs.move_files(path, destination)
return {"status": "moved", "from": path, "to": destination}
if action == "find":
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")}View on GitHub (pinned to 754d7323be)
Solutions
- Pass all three, with paths as a list: _run(action='replace', paths=['/a.txt', '/b.txt'], pattern='TODO', replacement='DONE').
- Pre-validate that replace calls include paths, pattern, and replacement.
- Highlight the paths-vs-path distinction in the agent-facing tool description.
Example fix
# before file_tool._run(action='replace', path='/a.txt', pattern='TODO', replacement='DONE') # after file_tool._run(action='replace', paths=['/a.txt'], pattern='TODO', replacement='DONE')
Defensive patterns
Strategy: validation
Validate before calling
def replace_in_files(file_tool, paths: list[str] | None, pattern: str | None, replacement: str | None):
if not paths or pattern is None or replacement is None:
raise ValueError("action='replace' requires 'paths', 'pattern', and 'replacement'")
if isinstance(paths, str):
paths = [paths] # accept a single file string
return file_tool._run(action='replace', paths=paths, pattern=pattern, replacement=replacement) Type guard
def is_paths_list(value: object) -> bool:
return isinstance(value, list) and bool(value) and all(isinstance(p, str) and p for p in value) Try / catch
try:
file_tool._run(action='replace', paths=paths, pattern=pattern, replacement=replacement)
except ValueError as e:
if 'replace' in str(e):
paths = paths or [last_written_path] # recover from singular-path mistake
file_tool._run(action='replace', paths=paths, pattern=pattern, replacement=replacement)
else:
raise Prevention
- Remember replace takes 'paths' (a list), not 'path' — encode this in a wrapper signature.
- Coerce single strings to one-element lists before calling.
- Add a JSON-schema check for replace calls in the agent dispatcher.
When it happens
Trigger: Calling _run(action='replace', path='/a.txt', pattern='x', replacement='y') — using singular 'path' is not read, so paths stays None; omitting 'replacement'; passing pattern only.
Common situations: Users carrying over the singular 'path' kwarg habit from other actions; agents emitting a single string instead of a list for paths; JSON tool calls that nest the three fields under a 'params' object.
Related errors
- action='delete' requires 'path'
- action='mkdir' requires 'path'
- action='info' requires 'path'
- action='exists' requires 'path'
- action='move' requires 'path' and 'destination'
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/20198b178edb0b69.
Report an issue: GitHub.