datawhalechina/hello-agents · warning · PatchApplyError
Too many files in patch: {len(set(touched_files))} > {self.m
Error message
Too many files in patch: {len(set(touched_files))} > {self.max_files} What it means
PatchApplyError raised by ApplyPatchExecutor when the number of distinct files touched by add/update/delete operations exceeds the executor's configured max_files limit. This is a guardrail against overly broad agent-generated patches; parsing succeeds but execution is refused before any file is modified.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:116
3. 创建备份目录
4. 逐个执行操作 (先备份再修改)
参数:
patch_text: 符合 Codex 风格的补丁文本,以 *** Begin Patch 开始,*** End Patch 结束
返回:
ApplyResult: 包含被修改文件和备份文件信息的结果对象
异常:
PatchApplyError: 当补丁不符合格式、超出限制或应用失败时抛出
"""
# 解析补丁文本,提取操作列表
ops = self._parse_patch(patch_text)
# 统计受影响的文件数量,检查是否超过限制
touched_files = [op[1] for op in ops if op[0] in {"add", "update", "delete"}]
if len(set(touched_files)) > self.max_files:
raise PatchApplyError(f"Too many files in patch: {len(set(touched_files))} > {self.max_files}")
# 估算补丁修改的总行数,检查是否超过限制
total_changed = self._estimate_changed_lines(ops)
if total_changed > self.max_total_changed_lines:
raise PatchApplyError(f"Patch too large: {total_changed} changed lines > {self.max_total_changed_lines}")
# 创建本次补丁应用的专属备份目录(时间戳命名)
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)View on GitHub (pinned to 606a07d341)
Solutions
- Split the patch into multiple smaller apply calls, each under the file limit.
- Reconsider scope: a focused patch per logical change is the intended usage.
- If the broad change is genuinely required, raise executor max_files in its constructor/config — but treat this as a policy decision, not a quick fix.
- Check the error message: it reports actual vs allowed counts.
Example fix
# before
executor.apply(big_patch) # touches 12 files, max_files=10 -> PatchApplyError
# after
for chunk in split_patch_by_file(big_patch, max_files=executor.max_files):
result = executor.apply(chunk) Defensive patterns
Strategy: validation
Validate before calling
ops = parse_patch(patch_text)
touched = {op.path for op in ops if op.kind in {"add", "update", "delete"}}
assert len(touched) <= executor.max_files, f"split patch: {len(touched)} > {executor.max_files}" Try / catch
try:
result = executor.apply(patch_text)
except PatchApplyError as e:
if str(e).startswith("Too many files"):
for chunk in split_patch_by_file(patch_text, executor.max_files):
executor.apply(chunk)
else:
raise Prevention
- Generate one patch per logical change instead of repo-wide refactors.
- Pre-check file counts against executor.max_files before submitting.
- Expose max_files in config so policy changes are deliberate, not ad hoc.
When it happens
Trigger: Submitting a patch whose set of '*** Add File'/'*** Update File'/'*** Delete File' targets exceeds max_files (e.g. 10 files with a limit of 5). Fails atomically — no backups or writes happen.
Common situations: LLM agent attempting a large refactor in one patch; limit lowered in config after workflows were built; batch scripts generating multi-file patches without chunking.
Related errors
- Patch too large: {total_changed} changed lines > {self.max_t
- Add File target already exists: {rel_path}
- Delete File target missing: {rel_path}
- Update File target missing: {rel_path}
- 工具 '{tool_name}' 不存在
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/9ab94adbe6758ed1.
Report an issue: GitHub.