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

  1. Pass the text explicitly: tool.run(action='append', path='/workspace/log.txt', content='new line').
  2. Check the exact field name is 'content' (not 'text'/'data') in the tool call.
  3. 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

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


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