NousResearch/hermes-agent · error · ValueError

path required

Error message

path required

What it means

Raised by _proposal_for_write_file in the ACP adapter when building an edit-approval proposal for a write_file tool call whose arguments contain no non-empty 'path' string. The proposal needs a target file to show the user a diff, so an empty/missing path is rejected before any filesystem access. It indicates the client sent a malformed tool-call payload, not a filesystem problem.

Source

Thrown at acp_adapter/edit_approval.py:85


def get_edit_approval_requester() -> EditApprovalRequester | None:
    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")

View on GitHub (pinned to c896c09c42)

Solutions

  1. Fix the caller to always send a non-empty absolute 'path' in write_file arguments.
  2. Align editor extension and ACP adapter versions so the tool schema matches.
  3. If an agent produced the call, tighten its tool schema to mark path as required.
  4. Catch ValueError in the ACP dispatcher and return it as an invalid-params error to the client.

Example fix

# before
path = str(arguments.get("path") or "")
if not path:
    raise ValueError("path required")

# after — validate the raw type too (reject path: 123 -> "123")
raw_path = arguments.get("path")
if not isinstance(raw_path, str) or not raw_path.strip():
    raise ValueError("path required (non-empty string)")
path = raw_path
Defensive patterns

Strategy: validation

Validate before calling

raw = arguments.get("path")
if not isinstance(raw, str) or not raw.strip():
    return invalid_params("write_file requires a non-empty 'path' string")

Type guard

def has_valid_path(args: dict[str, Any]) -> bool:
    p = args.get("path")
    return isinstance(p, str) and bool(p.strip())

Try / catch

try:
    proposal = _proposal_for_write_file(arguments)
except ValueError as err:
    return {"error": {"code": -32602, "message": str(err)}}  # invalid params -> client retries

Prevention

When it happens

Trigger: An ACP client (VS Code/Zed/JetBrains extension or an agent behind it) emits a write_file call with path omitted, empty string, or None (which str()s to '').

Common situations: Version mismatch between the editor extension and the tool schema; an LLM agent omitting required fields; JSON payloads where path was nested under the wrong key.

Related errors


AI-assisted analysis of NousResearch/hermes-agent@c896c09c42 (2026-08-14). Data as JSON: /api/errors/a283ab949b3ee3e3. Report an issue: GitHub.