{"record":{"id":"26099a2c0438d4d2","repo":"crewAIInc/crewAI","slug":"action-append-requires-content-pass-the-chunk","errorCode":null,"errorMessage":"action='append' requires 'content'. Pass the chunk to append in the 'content' field.","messagePattern":"action='append' requires 'content'\\. Pass the chunk to append in the 'content' field\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py","lineNumber":190,"sourceCode":"            \"For action='replace': list of absolute file paths in which to \"\n            \"replace 'pattern' with 'replacement'.\"\n        ),\n    )\n    owner: str | None = Field(\n        default=None,\n        description=\"For action='chmod': new file owner (user name).\",\n    )\n    group: str | None = Field(\n        default=None,\n        description=\"For action='chmod': new file group.\",\n    )\n\n    @model_validator(mode=\"after\")\n    def _validate_action_args(self) -> DaytonaFileToolSchema:\n        if self.action != \"replace\" and not self.path:\n            raise ValueError(f\"action={self.action!r} requires 'path'.\")\n        if self.action == \"append\" and self.content is None:\n            raise ValueError(\n                \"action='append' requires 'content'. Pass the chunk to append \"\n                \"in the 'content' field.\"\n            )\n        if self.action == \"move\" and not self.destination:\n            raise ValueError(\"action='move' requires 'destination'.\")\n        if self.action == \"find\" and not self.pattern:\n            raise ValueError(\n                \"action='find' requires 'pattern' (text to search for inside files).\"\n            )\n        if self.action == \"search\" and not self.pattern:\n            raise ValueError(\"action='search' requires 'pattern' (glob, e.g. '*.py').\")\n        if self.action == \"chmod\" and not (self.mode or self.owner or self.group):\n            raise ValueError(\n                \"action='chmod' requires at least one of 'mode', 'owner', or 'group'.\"\n            )\n        if self.action == \"replace\":\n            if not self.paths:\n                raise ValueError(","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/daytona_sandbox_tool/daytona_file_tool.py#L172-L208","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\ntool.run(action=\"append\", path=\"/workspace/log.txt\")  # ValueError\n\n# after\ntool.run(action=\"append\", path=\"/workspace/log.txt\", content=\"line added\\n\")","handlingStrategy":"validation","validationCode":"def validate_append(path: str | None, content: str | None) -> None:\n    if not path:\n        raise ValueError(\"append requires path\")\n    if content is None:\n        raise ValueError(\"append requires explicit content (use '' only if intended)\")\n\nvalidate_append(path, content)","typeGuard":null,"tryCatchPattern":"try:\n    tool.run(action=\"append\", path=p, content=c)\nexcept ValidationError as e:\n    if \"requires 'content'\" in str(e):\n        c = prompt_for_content()\n        tool.run(action=\"append\", path=p, content=c)\n    else:\n        raise","preventionTips":["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."],"tags":["daytona","pydantic","validation","input-validation","filesystem"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}