datawhalechina/hello-agents · error · PatchApplyError
Delete File target missing: {rel_path}
Error message
Delete File target missing: {rel_path} What it means
PatchApplyError raised when a '*** Delete File' operation targets a path that does not exist. The executor verifies presence before deleting (and before creating a backup), so a stale or mistyped delete target aborts. Because operations run sequentially, earlier ops in the same patch may already have been applied — this failure is not rolled back automatically.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:153
# 安全检查:确保文件后缀在允许的列表中
self._enforce_suffix(target)
if kind == "add":
# 添加新文件操作
if target.exists():
raise PatchApplyError(f"Add File target already exists: {rel_path}")
# 创建父目录(如果不存在)
target.parent.mkdir(parents=True, exist_ok=True)
# 原子写入新文件内容
self._atomic_write(target, payload)
# 记录变更
files_changed.append(rel_path)
elif kind == "delete":
# 删除文件操作
if not target.exists():
raise PatchApplyError(f"Delete File target missing: {rel_path}")
# 删除前先备份文件
b = self._backup_file(target, backup_run_dir)
backups.append(str(b))
# 删除文件
target.unlink()
# 记录变更
files_changed.append(rel_path)
elif kind == "update":
# 更新文件操作
if not target.exists():
raise PatchApplyError(f"Update File target missing: {rel_path}")
# 读取原始文件内容(保留换行符)
original = target.read_text(encoding="utf-8").splitlines(keepends=True)
# 修改前先备份文件
b = self._backup_file(target, backup_run_dir)
backups.append(str(b))
# 应用更新补丁内容View on GitHub (pinned to 606a07d341)
Solutions
- Regenerate the patch against the current tree state (re-list files before planning deletes).
- If re-applying, filter out delete ops for files already gone (treat as satisfied).
- Restore from the timestamped backup directory if a partial apply left the tree inconsistent.
Example fix
# before patch deletes 'src/old.py' but it was already removed -> PatchApplyError # after ops = [op for op in parse(patch) if not (op.kind == 'delete' and not Path(op.path).exists())] patch = serialize(ops)
Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
missing = [p for p in delete_targets if not Path(repo_root, p).exists()]
if missing:
patch = drop_ops(patch, missing) # already-deleted targets are satisfied Type guard
from pathlib import Path
def filter_stale_deletes(ops):
"""Drop delete ops whose targets no longer exist (idempotent re-apply)."""
return [op for op in ops if op.kind != "delete" or Path(op.path).exists()] Try / catch
try:
executor.apply(patch_text)
except PatchApplyError as e:
if "Delete File target missing" in str(e):
# partial apply possible: verify tree state, then re-apply filtered patch
... Prevention
- Re-list the working tree immediately before generating delete operations.
- Make re-application idempotent by filtering already-satisfied deletes.
- Watch for case-sensitivity and path-separator mismatches between patch and filesystem.
When it happens
Trigger: Patch contains Delete File for a path already removed (double-apply), a typo'd path, or a file deleted by a concurrent process between patch generation and execution.
Common situations: Re-running a patch that partially succeeded earlier; agent's file listing out of date; case-sensitivity or path-separator mismatches.
Related errors
- Add File target already exists: {rel_path}
- Update File target missing: {rel_path}
- Too many files in patch: {len(set(touched_files))} > {self.m
- Patch too large: {total_changed} changed lines > {self.max_t
- 工具 '{tool_name}' 不存在
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/acc4bd1c2648846a.
Report an issue: GitHub.