{"record":{"id":"531a4fbbed535a54","repo":"crewAIInc/crewAI","slug":"action-append-requires-content-pass-the-chunk-531a4f","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/e2b_sandbox_tool/e2b_file_tool.py","lineNumber":61,"sourceCode":"        ),\n    )\n    binary: bool = Field(\n        default=False,\n        description=(\n            \"For 'write'/'append': treat content as base64 and upload raw \"\n            \"bytes. For 'read': return contents as base64 instead of decoded \"\n            \"utf-8.\"\n        ),\n    )\n    depth: int = Field(\n        default=1,\n        description=\"For action='list': how many levels deep to recurse (default 1).\",\n    )\n\n    @model_validator(mode=\"after\")\n    def _validate_action_args(self) -> E2BFileToolSchema:\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        return self\n\n\nclass E2BFileTool(E2BBaseTool):\n    \"\"\"Read, write, and manage files inside an E2B sandbox.\n\n    Notes:\n      - Most useful with `persistent=True` or an explicit `sandbox_id`. With\n        the default ephemeral mode, files disappear when this tool call\n        finishes.\n    \"\"\"\n\n    name: str = \"E2B Sandbox Files\"\n    description: str = (\n        \"Perform filesystem operations inside an E2B sandbox: read a file, \"","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/crewAIInc/crewAI/blob/754d7323beb2fd042e33444a115ea2d5a47193f0/lib/crewai-tools/src/crewai_tools/tools/e2b_sandbox_tool/e2b_file_tool.py#L43-L79","documentation":"Raised by a Pydantic model_validator (mode='after') on E2BFileToolSchema when the tool is invoked with action='append' but no 'content' field. The schema enforces that append operations carry the chunk of data to append, since appending nothing is meaningless. It fires at input-validation time, before any sandbox call is made.","triggerScenarios":"Calling E2BFileTool._run(action='append', path='/tmp/log.txt') without passing content, or passing content=None explicitly (e.g. an LLM agent omitting the argument, or a dict-based invocation that drops the key).","commonSituations":"An LLM agent using the tool decides to 'append' but leaves content out of its action input; programmatic callers building kwargs conditionally and skipping content when the buffer is empty.","solutions":["Pass the data to append: tool._run(action='append', path='/tmp/log.txt', content='new line\\n').","If the content may be empty, guard on your side: only invoke append when the chunk is non-empty.","If appending nothing is intentional, skip the tool call entirely instead of calling append with no content."],"exampleFix":"# before\ntool._run(action='append', path='/tmp/log.txt')\n\n# after\ntool._run(action='append', path='/tmp/log.txt', content='new line\\n')","handlingStrategy":"validation","validationCode":"def build_append_args(path: str, chunk: str | None) -> dict:\n    if not chunk:\n        raise ValueError('refusing to append empty/missing content')\n    return {'action': 'append', 'path': path, 'content': chunk}","typeGuard":null,"tryCatchPattern":"from pydantic import ValidationError\ntry:\n    tool._run(action='append', path=p, content=c)\nexcept ValidationError as e:\n    logger.warning('append rejected: %s', e.errors()[0]['msg'])","preventionTips":["Always construct tool args as an explicit dict including content for append actions.","Skip the tool call when the append chunk is empty instead of sending None."],"tags":["pydantic","validation","e2b","tool-args"],"backgroundTag":null,"analyzedSha":"754d7323beb2fd042e33444a115ea2d5a47193f0","analyzedAt":"2026-08-15T04:06:56.746Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}