crewAIInc/crewAI · error · ValueError
action='append' requires 'content'. Pass the chunk to append
Error message
action='append' requires 'content'. Pass the chunk to append in the 'content' field.
What it means
DaytonaFileToolSchema._validate_action_args requires that action='append' comes with content (the chunk to append). content is Optional, so Pydantic itself will not reject its absence; this validator catches it and raises ValueError so the call fails fast with a clear message instead of silently appending nothing.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py:190
"For action='replace': list of absolute file paths in which to "
"replace 'pattern' with 'replacement'."
),
)
owner: str | None = Field(
default=None,
description="For action='chmod': new file owner (user name).",
)
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(View on GitHub (pinned to 754d7323be)
Solutions
- Pass the text explicitly: tool.run(action='append', path='/workspace/log.txt', content='new line').
- Check the exact field name is 'content' (not 'text'/'data') in the tool call.
- If you genuinely want to create/overwrite a file, use action='write' with content; for append-only semantics always supply content.
Example fix
# before tool.run(action="append", path="/workspace/log.txt") # ValueError # after tool.run(action="append", path="/workspace/log.txt", content="line added\n")
Defensive patterns
Strategy: validation
Validate before calling
def validate_append(path: str | None, content: str | None) -> None:
if not path:
raise ValueError("append requires path")
if content is None:
raise ValueError("append requires explicit content (use '' only if intended)")
validate_append(path, content) Try / catch
try:
tool.run(action="append", path=p, content=c)
except ValidationError as e:
if "requires 'content'" in str(e):
c = prompt_for_content()
tool.run(action="append", path=p, content=c)
else:
raise Prevention
- Map your payload field names exactly to the schema (path, content, destination, pattern, replacement, paths, mode, owner, group).
- Reject agent-generated calls missing content before execution.
- Use action='write' when creating/overwriting rather than append with defaults.
When it happens
Trigger: Calling DaytonaFileTool with action='append' and a path but no content, or content explicitly None; an agent intending to append text but mapping the payload into the wrong field name.
Common situations: LLM tool call includes path but names the payload field differently (e.g. 'text' or 'data'); caller assumes append with empty string is a no-op they want — the schema demands an explicit value; content=None passed positionally by mistake.
Related errors
- action={self.action!r} requires 'path'.
- action='move' requires 'destination'.
- action='replace' requires 'paths' (list of file paths).
- action='replace' requires 'pattern'.
- action='replace' requires 'replacement'.
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/26099a2c0438d4d2.
Report an issue: GitHub.