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
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.
Source
Thrown at lib/crewai-tools/src/crewai_tools/tools/e2b_sandbox_tool/e2b_file_tool.py:61
),
)
binary: bool = Field(
default=False,
description=(
"For 'write'/'append': treat content as base64 and upload raw "
"bytes. For 'read': return contents as base64 instead of decoded "
"utf-8."
),
)
depth: int = Field(
default=1,
description="For action='list': how many levels deep to recurse (default 1).",
)
@model_validator(mode="after")
def _validate_action_args(self) -> E2BFileToolSchema:
if self.action == "append" and self.content is None:
raise ValueError(
"action='append' requires 'content'. Pass the chunk to append "
"in the 'content' field."
)
return self
class E2BFileTool(E2BBaseTool):
"""Read, write, and manage files inside an E2B sandbox.
Notes:
- Most useful with `persistent=True` or an explicit `sandbox_id`. With
the default ephemeral mode, files disappear when this tool call
finishes.
"""
name: str = "E2B Sandbox Files"
description: str = (
"Perform filesystem operations inside an E2B sandbox: read a file, "View on GitHub (pinned to 754d7323be)
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.
Example fix
# before tool._run(action='append', path='/tmp/log.txt') # after tool._run(action='append', path='/tmp/log.txt', content='new line\n')
Defensive patterns
Strategy: validation
Validate before calling
def build_append_args(path: str, chunk: str | None) -> dict:
if not chunk:
raise ValueError('refusing to append empty/missing content')
return {'action': 'append', 'path': path, 'content': chunk} Try / catch
from pydantic import ValidationError
try:
tool._run(action='append', path=p, content=c)
except ValidationError as e:
logger.warning('append rejected: %s', e.errors()[0]['msg']) Prevention
- 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.
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- Unknown action: {action}
- Missing required input '{name}'{suffix}
- Invalid input '{location}': {error.get('msg')}
- Expected an async readable object with async read() method
- Expected a binary file-like object with read() and seek()
AI-assisted analysis of crewAIInc/crewAI@754d7323be (2026-08-15).
Data as JSON: /api/errors/531a4fbbed535a54.
Report an issue: GitHub.