datawhalechina/hello-agents · error · PatchApplyError

Patch hunk context not found; file changed?

Error message

Patch hunk context not found; file changed?

What it means

Raised when the hunk's before/context lines cannot be found as an exact contiguous subsequence of the current file content (_find_subsequence returns None). It means the file on disk differs from what the patch author saw — concurrent edits, stale context, or whitespace mismatches. The error carries a recheck_targets hint ('file:search:\'context line\'') so an agent can re-read the file.

Source

Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:467

                continue
            tag = l[0]
            text = l[1:] + "\n"
            if tag == " ":
                before.append(text)
                after.append(text)
            elif tag == "-":
                before.append(text)
            elif tag == "+":
                after.append(text)

        if not before:
            raise PatchApplyError("Update hunk has no context/removals; refusing to apply")

        idx = self._find_subsequence(current, before)
        if idx is None:
            context_line = next((b.strip() for b in before if b.strip()), "")
            hint = f"{rel_path}:search:'{context_line[:80]}'"
            raise PatchApplyError("Patch hunk context not found; file changed?", recheck_targets=[hint])

        return current[:idx] + after + current[idx + len(before) :]

    def _find_subsequence(self, haystack: List[str], needle: List[str]) -> Optional[int]:
        """
        在文件内容中查找代码块的起始位置。
        使用简单的 O(N*M) 字符串匹配算法,在 haystack 中查找 needle 的精确匹配。
        
        参数:
            haystack: 文件内容行列表
            needle: 要查找的代码块行列表
            
        返回:
            Optional[int]: 匹配的起始行索引,如果未找到则返回 None
        """
        if len(needle) > len(haystack):
            return None
        for i in range(0, len(haystack) - len(needle) + 1):

View on GitHub (pinned to 606a07d341)

Solutions

  1. Re-read the target file (the recheck_targets hint gives the search string) and regenerate the hunk from current content.
  2. Apply pending patches to the same file serially, re-reading after each apply.
  3. Check for whitespace/line-ending drift; include context lines copied verbatim from the file.

Example fix

# before
except PatchApplyError as e:
    if e.recheck_targets:
        abort()  # give up

# after
except PatchApplyError as e:
    if e.recheck_targets:
        fresh = read_file(rel_path)         # re-read current content
        patch = regenerate_hunk(fresh)       # rebuild context lines
        result = executor.apply(patch)       # retry once
Defensive patterns

Strategy: retry

Validate before calling

current = (repo_root / rel_path).read_text().splitlines()
context = [l[1:] + '\n' for l in hunk_lines if l.startswith((' ', '-'))]
if executor._find_subsequence(current, context) is None:
    raise ValueError('context stale; re-read file and regenerate hunk')

Try / catch

try:
    executor.apply(patch_text)
except PatchApplyError as e:
    if 'context not found' in str(e):
        fresh = read_target_files(e.recheck_targets)   # re-read current state
        patch_text = regenerate_hunks(fresh)            # rebuild from reality
        return executor.apply(patch_text)               # one bounded retry
    raise

Prevention

When it happens

Trigger: Applying a patch generated against an older revision; two patches to the same file applied in the wrong order; whitespace/indentation drift (tabs vs spaces) between the patch context and the file; CRLF vs LF line endings.

Common situations: Agent applies multiple sequential patches without re-reading the file between them; another process (formatter, linter, human) touched the file; patch context copied with normalized indentation.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/a7a433306c27028e. Report an issue: GitHub.