datawhalechina/hello-agents · error · PatchApplyError
Update hunk has no context/removals; refusing to apply
Error message
Update hunk has no context/removals; refusing to apply
What it means
Raised while applying an Update File hunk when the 'before' side is empty — the hunk contains only '+' additions and no context (' ') or removal ('-') lines. Pure-insertion hunks are rejected because _find_subsequence has no anchor to locate where the new lines belong, making the write position ambiguous.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:461
PatchApplyError: 当 hunk 格式错误或找不到匹配的上下文时抛出
"""
before: List[str] = []
after: List[str] = []
for l in hunk_lines:
if not l:
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: 要查找的代码块行列表
View on GitHub (pinned to 606a07d341)
Solutions
- For new files, use '*** Add File: ' with the full content instead of Update.
- For insertions into an existing file, include at least one unchanged context line (prefixed with a single space) above or below the '+' lines.
- For end-of-file appends, quote the final existing line(s) as context, then the '+' lines.
Example fix
# before
*** Update File: notes.py
+def new_fn():
+ pass
*** End Patch
# after
*** Update File: notes.py
def existing_fn():
pass
+
+def new_fn():
+ pass Defensive patterns
Strategy: validation
Validate before calling
def hunk_has_anchor(body: str) -> bool:
lines = [l for l in body.splitlines() if l.strip()]
return any(not l.startswith('+') for l in lines) # needs ' ' or '-' lines Try / catch
try:
executor.apply(patch_text)
except PatchApplyError as e:
if 'no context/removals' in str(e):
# convert to Add File if new, else add surrounding context lines
patch_text = add_context_lines(patch_text, file_content)
executor.apply(patch_text) Prevention
- Always include at least one unchanged context line in Update hunks.
- Use Add File for brand-new files, never Update.
- Teach the model the hunk grammar with anchor requirements.
When it happens
Trigger: An Update File body whose every line starts with '+': e.g. trying to append to a file via Update with no surrounding context; models adding a new function but forgetting to include the surrounding context lines.
Common situations: LLM uses Update File where Add File was intended (new file, all-plus body); appending to the end of a file without quoting the last existing lines; patch-generation tools that emit zero-context diffs.
Related errors
- Patch must start with '*** Begin Patch'
- Unknown op kind: {kind}
- Absolute paths are not allowed: {rel_path}
- Path escapes repo_root: {rel_path}
- Refusing to modify symlink: {rel_path}
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/d01b2030ec40cba2.
Report an issue: GitHub.