datawhalechina/hello-agents · error · PatchApplyError
Disallowed file suffix for write: {target.suffix}
Error message
Disallowed file suffix for write: {target.suffix} What it means
Raised by _enforce_suffix when the target file has a non-empty suffix that is not in the executor's allowed_write_suffixes allowlist. This confines writes to known-safe text file types and blocks accidental edits to binaries, lockfiles, secrets, and config files. Files with no suffix at all (Makefile, Dockerfile) pass through.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/code_agent/executors/apply_patch_executor.py:221
if not str(target).startswith(str(self.repo_root.resolve()) + os.sep) and target != self.repo_root.resolve():
raise PatchApplyError(f"Path escapes repo_root: {rel_path}")
if target.exists() and target.is_symlink():
raise PatchApplyError(f"Refusing to modify symlink: {rel_path}")
return target
def _enforce_suffix(self, target: Path) -> None:
"""
检查目标文件的后缀是否在允许的列表中。
防止意外修改二进制文件、配置文件或其他敏感文件。
参数:
target: 目标文件路径对象
异常:
PatchApplyError: 当文件后缀不在允许列表中时抛出
"""
if target.suffix and target.suffix not in self.allowed_write_suffixes:
raise PatchApplyError(f"Disallowed file suffix for write: {target.suffix}")
def _backup_file(self, target: Path, backup_run_dir: Path) -> Path:
"""
备份目标文件到指定的备份目录。
备份文件保持与原文件相同的相对路径结构,后缀添加 .bak。
参数:
target: 要备份的目标文件路径
backup_run_dir: 本次运行的备份目录
返回:
Path: 创建的备份文件路径
"""
# 获取文件相对于仓库根目录的路径
rel = target.relative_to(self.repo_root)
# 构建备份文件路径
backup_path = backup_run_dir / (str(rel) + ".bak")
# 创建备份文件的父目录(如果不存在)View on GitHub (pinned to 606a07d341)
Solutions
- Change the patch to target an allowed text file, or split binary/asset edits out of the patch workflow.
- If the extension is genuinely safe to edit, add it to the allowed_write_suffixes list when constructing the executor.
- For extensionless files, confirm they pass (no suffix) rather than fighting the allowlist.
Example fix
# before
executor = ApplyPatchExecutor(repo_root=root) # default allowlist
patch targets 'config/secrets.env' -> PatchApplyError
# after
executor = ApplyPatchExecutor(
repo_root=root,
allowed_write_suffixes={'.py', '.md', '.txt', '.yaml', '.json'},
) Defensive patterns
Strategy: validation
Validate before calling
ALLOWED = executor.allowed_write_suffixes
for kind, path, _ in executor._parse_patch(patch_text):
suffix = Path(path).suffix
if suffix and suffix not in ALLOWED:
raise ValueError(f'{path}: suffix {suffix} not in allowlist; edit an allowed file type') Type guard
def suffix_allowed(path: str, allowed: set) -> bool:
s = Path(path).suffix
return (not s) or (s in allowed) Try / catch
try:
executor.apply(patch)
except PatchApplyError as e:
if 'Disallowed file suffix' in str(e):
drop_disallowed_files_from_patch_and_retry()
raise Prevention
- Configure allowed_write_suffixes explicitly at executor construction.
- Instruct the agent never to patch binaries, lockfiles, or .env files.
- Validate all patch target suffixes before apply().
When it happens
Trigger: Patching a .env, .bin, .pem, .lock, or any extension not in allowed_write_suffixes; creating a new file with a disallowed extension via '*** Add File: '.
Common situations: Agent tries to edit package-lock.json, .env, or an image; a project policy allowlist that omits a legitimate extension (e.g. .md, .yaml) the team needs; generated patches referencing asset files.
Related errors
- Unknown op kind: {kind}
- Unexpected patch line: {line}
- 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/1a82d1d112c48e60.
Report an issue: GitHub.