datawhalechina/hello-agents · error · PatchApplyError
Add File target already exists: {rel_path}
Error message
Add File target already exists: {rel_path} What it means
PatchApplyError raised when an '*** Add File' operation targets a path that already exists on disk. The executor treats Add as create-only to avoid clobbering existing content; updates must use the update operation. Raised before any write, and per-file: earlier operations in the same patch may already have been applied.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:142
backup_run_dir = self.backups_dir / datetime.now().strftime("%Y%m%d_%H%M%S")
backup_run_dir.mkdir(parents=True, exist_ok=True)
# 初始化结果收集变量
files_changed: List[str] = [] # 记录被修改的文件路径
backups: List[str] = [] # 记录创建的备份文件路径
# 遍历所有解析出的操作,逐个执行
for kind, rel_path, payload in ops:
# 安全检查:确保路径在仓库内,防止路径遍历攻击
target = self._safe_path(rel_path)
# 安全检查:确保文件后缀在允许的列表中
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)View on GitHub (pinned to 606a07d341)
Solutions
- Change the operation to Update (with the proper update payload) if the file should be modified.
- Delete or move the existing file first if a fresh create is truly intended.
- If re-applying after a partial failure, restore from the executor's backup dir first, or check files_changed from the failed ApplyResult.
- Make apply idempotent client-side: check existence and choose add vs update accordingly.
Example fix
# before
patch = '*** Begin Patch\n*** Add File: src/new.py\n+...\n*** End Patch' # but src/new.py exists
# after
import pathlib
op = 'Update File: src/new.py' if pathlib.Path('src/new.py').exists() else 'Add File: src/new.py' Defensive patterns
Strategy: type-guard
Validate before calling
from pathlib import Path
if Path(repo_root, rel_path).exists():
raise ValueError(f"{rel_path} already exists; use an update op, not add") Type guard
from pathlib import Path
def choose_op(rel_path: str) -> str:
"""Return the patch op kind that will not conflict for this path."""
return "Update File" if (Path(rel_path).is_file()) else "Add File" Try / catch
try:
result = executor.apply(patch_text)
except PatchApplyError as e:
if "already exists" in str(e):
# regenerate patch with Update ops for existing files, then re-apply
... # note: earlier ops in this patch may already be applied
raise Prevention
- Check target existence right before generating the patch, not from a stale file listing.
- Never re-apply a partially failed patch wholesale; reconcile state first.
- Use the executor's backups directory to restore after partial applies.
When it happens
Trigger: A patch with '*** Add File: path' where path exists — typically because the agent thought the file was new, or the same patch is applied twice, or a prior partial apply left the file behind.
Common situations: Re-running a failed patch without cleanup; agent hallucinating that a file is absent; racing processes creating the file between planning and apply.
Related errors
- Delete File target missing: {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/b29eb709d07b5e0b.
Report an issue: GitHub.