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

  1. Regenerate the patch against the current tree state (re-list files before planning deletes).
  2. If re-applying, filter out delete ops for files already gone (treat as satisfied).
  3. 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

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


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