NousResearch/hermes-agent · error · ValueError
content required
Error message
content required
What it means
Raised by _proposal_for_write_file when the tool-call arguments lack 'content' (it is None). write_file's whole purpose is to write content, and the approval diff is built from old_text vs the new content — without content there is no proposal to approve. Note the check is `is None`, so an empty string is accepted intentionally (writing an empty file is legal).
Source
Thrown at acp_adapter/edit_approval.py:88
return _EDIT_APPROVAL_REQUESTER.get()
def _read_text_if_exists(path: str) -> str | None:
p = Path(path).expanduser()
if not p.exists():
return None
if not p.is_file():
raise OSError(f"Cannot edit non-file path: {path}")
return p.read_text(encoding="utf-8", errors="replace")
def _proposal_for_write_file(arguments: dict[str, Any]) -> EditProposal:
path = str(arguments.get("path") or "")
if not path:
raise ValueError("path required")
content = arguments.get("content")
if content is None:
raise ValueError("content required")
return EditProposal(
tool_name="write_file",
path=path,
old_text=_read_text_if_exists(path),
new_text=str(content),
arguments=dict(arguments),
)
def _proposal_for_patch_replace(arguments: dict[str, Any]) -> EditProposal:
path = str(arguments.get("path") or "")
if not path:
raise ValueError("path required")
old_string = arguments.get("old_string")
new_string = arguments.get("new_string")
if old_string is None or new_string is None:
raise ValueError("old_string and new_string required")
View on GitHub (pinned to c896c09c42)
Solutions
- Send 'content' (string, possibly empty) in every write_file call.
- Align the tool schema between the agent/client and the adapter — one canonical field name.
- If the agent uses a different key, normalize arguments at the ACP boundary before proposal building.
- Return the error to the client as invalid-params so the agent can retry with a correct payload.
Example fix
# before
content = arguments.get("content")
if content is None:
raise ValueError("content required")
# after — tolerate common aliases, still require presence
content = arguments.get("content", arguments.get("contents"))
if content is None:
raise ValueError("content required") Defensive patterns
Strategy: validation
Validate before calling
if "content" not in arguments or arguments["content"] is None:
return invalid_params("write_file requires 'content' (use '' for an empty file)") Type guard
def has_content(args: dict[str, Any]) -> bool:
return args.get("content") is not None Try / catch
try:
proposal = _proposal_for_write_file(arguments)
except ValueError as err:
return {"error": {"code": -32602, "message": str(err)}} Prevention
- Document that content may be '' but must be present
- Normalize alternative keys (contents/text) at the boundary
- Add schema validation (jsonschema/pydantic) on incoming tool arguments
When it happens
Trigger: An ACP write_file call whose JSON arguments omit 'content' or pass null — e.g. an agent that streams content separately and forgot the field, or a schema/client mismatch where the field is named differently (text/contents).
Common situations: Editor extension versions disagreeing on the write_file schema; LLM agents emitting {path, contents} instead of {path, content}; hand-rolled ACP clients.
Related errors
- path required
- Cannot edit non-file path: {path}
- old_string and new_string required
- patch content required
- no file paths found in V4A patch
AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14).
Data as JSON: /api/errors/5cae9c672dd78a20.
Report an issue: GitHub.