NousResearch/hermes-agent · error · ValueError

no file paths found in V4A patch

Error message

no file paths found in V4A patch

What it means

Raised by _proposal_for_patch_v4a after receiving a syntactically-present patch string from which _extract_v4a_patch_paths could extract no file paths (it scans diff headers like '--- a/...' / '+++ b/...' pairs). With no paths there is no file to attribute the proposal to, so approval cannot proceed. It means the diff body is not in a header format the extractor recognizes — not that the files are missing on disk.

Source

Thrown at acp_adapter/edit_approval.py:162

        re.MULTILINE,
    ):
        src = match.group(1).strip()
        dst = match.group(2).strip()
        if src:
            paths.append(src)
        if dst:
            paths.append(dst)
    return paths


def _proposal_for_patch_v4a(arguments: dict[str, Any]) -> EditProposal:
    patch_body = arguments.get("patch")
    if not isinstance(patch_body, str) or not patch_body:
        raise ValueError("patch content required")

    paths = _extract_v4a_patch_paths(patch_body)
    if not paths:
        raise ValueError("no file paths found in V4A patch")

    proposal_path = paths[0] if len(paths) == 1 else ", ".join(paths)
    old_text = _read_text_if_exists(paths[0]) if len(paths) == 1 else None
    return EditProposal(
        tool_name="patch",
        path=proposal_path,
        old_text=old_text,
        # ACP only supports a single diff payload here.  Surface the exact V4A
        # patch content before execution so patch-mode calls are permissioned
        # and denied patches cannot mutate.
        new_text=patch_body,
        arguments=dict(arguments),
    )


def build_edit_proposal(tool_name: str, arguments: dict[str, Any]) -> EditProposal | None:
    """Return an edit proposal for supported file mutation calls."""

View on GitHub (pinned to c896c09c42)

Solutions

  1. Ensure the patch includes standard '--- a/<path>' and '+++ b/<path>' header lines before each hunk.
  2. Regenerate the diff with `git diff` / `diff -u` rather than hand-editing, and send it unescaped.
  3. For new-file diffs, include the /dev/null pairing so at least the '+++' path is extracted.
  4. As a maintainer: extend _extract_v4a_patch_paths to also read 'diff --git a/... b/...' lines as a fallback.

Example fix

# before (hunks only, no headers -> 'no file paths found in V4A patch')
"@@ -1,3 +1,4 @@\n context\n+new line"

# after (headers included)
"--- a/src/app.ts\n+++ b/src/app.ts\n@@ -1,3 +1,4 @@\n context\n+new line"
Defensive patterns

Strategy: validation

Validate before calling

import re
def has_diff_file_headers(patch: str) -> bool:
    return bool(re.search(r'^(---|\+\+\+|diff --git) ', patch, re.MULTILINE))
if not has_diff_file_headers(patch_body):
    return invalid_params('patch must include ---/+++ (or diff --git) file headers')

Type guard

def is_headered_unified_diff(patch: str) -> bool:
    return re.search(r'^--- (a/)?\S+\n\+\+\+ (b/)?\S+', patch, re.MULTILINE) is not None

Try / catch

try:
    proposal = _proposal_for_patch_v4a(arguments)
except ValueError as err:
    if 'no file paths' in str(err):
        # ask the sender to regenerate with `git diff` so headers are present
        return {"error": {"code": -32602, "message": 'patch missing ---/+++ headers; regenerate with git diff'}}
    raise

Prevention

When it happens

Trigger: A patch payload in a format whose headers the regex misses: git-style diffs with renamed/broken headers, contextless 'ed'-style or custom diff dialects, a patch whose lines were escaped/quoted so '---'/'+++' no longer match, or hunks concatenated without their file headers.

Common situations: Clients sending only hunk bodies (@@ sections) without the ---/+++ header lines; diff producers using 'diff --git' without the following ---/+++ pair (e.g. binary or rename-only diffs); payloads mangled by JSON string escaping or HTML-entity encoding.

Related errors


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