所有文章

Claude Code 报 Error editing file 怎么办?按 Ctrl+O 看真正原因(5 种拒绝实测)

界面上一行 Error editing file 不会告诉你原因,按 Ctrl+O 打开 transcript 才有完整报错。我们在 Claude Code 2.1.312 上用本地模拟接口复现了 5 种拒绝,逐条抄下原文,并给出对应的改法。

Claude Code Error editing file:黏土终端块旁边一块有裂纹的文件小卡片和薄荷绿铅笔,柔和自然光

先说结论:Claude Code 界面里那行 Error editing file 只是个简称,真正的原因在完整的工具报错里,按 Ctrl+O 打开 transcript 就能看到。我们 2026 年 11 月 10 日在 Claude Code 2.1.312 上,用一个本地的模拟接口(没有登录、没有连 Anthropic)复现了 5 种常见的拒绝:文件不是 UTF-8、被 Read deny 规则挡住、写的是软链接、没先读就改、要替换的文字对不上,并把完整原文抄在下面。

第一步:按 Ctrl+O 看完整报错

官方 Error reference(我们 11-10 抓取,文中版本号到 v2.1.318)在「路径无法安全解析」那一条里写明:被拦下的文件编辑,对话视图只显示一行短短的 Error editing file,完整信息在 transcript 视图里,用 Ctrl+O 打开。完整信息同时也会作为工具报错发给 Claude,所以多数时候 Claude 会自己换个办法重试。

我们没能在交互界面里截到这一行短提示:测试用的是 claude -p(非交互模式),它直接给出完整的工具结果。下面所有原文都是这样拿到的。

5 种原因对照表

先用 Ctrl+O 拿到完整一行,再按开头对表:

完整报错开头意思怎么办依据
File is not valid UTF-8: it uses a legacy encoding such as Windows-1252, Shift-JIS or GBK, or it is binary.文件不是 UTF-8(GBK 老文件最常见),没有写入任何内容先转成 UTF-8,或让 Claude 用 shell 命令按原编码改官方文档 + 2.1.312 实测
File is covered by a Read deny rule in your permission settings and cannot be edited.permissions.deny 里有 Read 规则命中了这个路径收窄或删掉那条 Read deny官方文档 + 2.1.312 实测
Refusing to write /path/CLAUDE.md: it is a symbolic link. Write to the link's target path instead: /path/AGENTS.md.要写的位置本身是软链接改它指向的真实文件官方文档 + 2.1.312 实测
File has not been read yet. Read it first before writing to it.这个会话里 Claude 还没读过这个文件让 Claude 先读再改2.1.312 实测(文档里没找到这一条)
String to replace not found in file.Claude 给的旧文字和文件内容对不上,文件可能已经被改过让 Claude 重新读一遍再改2.1.312 实测(文档里没找到这一条)

我们是怎么复现的

环境:Claude Code 2.1.312(claude --version),ANTHROPIC_BASE_URL 指向本机一个几十行的 Python 小服务。它冒充 Messages API,只会按脚本依次发出 Read、Edit 的工具调用,没有真模型,也没有任何请求发给 Anthropic。命令是 claude -p 加 --permission-mode acceptEdits。

1. 非 UTF-8 文件。 先造一个 GBK 文件:

printf '你好,世界\n版本=1\n' | iconv -f UTF-8 -t GBK > gbk.txt

Claude 先 Read,结果末尾多了一句提示:[This file is not valid UTF-8: it uses a legacy encoding such as Windows-1252, Shift-JIS or GBK, or it is binary. ...]。接着 Edit 被拒,完整原文(外层的 tool_use_error 标签省略):

File is not valid UTF-8: it uses a legacy encoding such as Windows-1252, Shift-JIS or GBK, or it is binary. These tools write UTF-8 (or UTF-16LE behind its byte-order mark) and never convert a file's encoding on their own, so nothing was written. If the file is text, make the change with a shell command that reads and writes it in its own encoding (iconv, or PowerShell Get-Content/Set-Content -Encoding), or ask the user whether to convert it to UTF-8 first. To replace the whole file with new UTF-8 text anyway, delete it first, then Write it.

文档里同一条的措辞(It may use a legacy encoding ... Nothing was written.)和 2.1.312 的实际输出不完全一样,以你屏幕上的为准,关键词 File is not valid UTF-8 是一样的。文档还写了:v2.1.296 之前 Edit 会直接把读不出来的字节存成 U+FFFD,也就是悄悄把文件改坏,所以老版本要先升级。

2. Read deny 规则。 项目的 .claude/settings.json 写 {"permissions":{"deny":["Read(./secret.txt)"]}},让 Claude 改 secret.txt,得到:

File is covered by a Read deny rule in your permission settings and cannot be edited.

3. 软链接。 造 CLAUDE.md 指向 AGENTS.md(ln -s AGENTS.md CLAUDE.md),让 Claude 先读再改 CLAUDE.md:

Refusing to write /tmp/cct/proj/CLAUDE.md: it is a symbolic link. Write to the link's target path instead: /tmp/cct/proj/AGENTS.md.

4. 没先读 / 文字对不上。 直接 Edit 一个没读过的文件,得到 File has not been read yet. Read it first before writing to it.;读过之后用一个文件里没有的旧文字去替换,得到 String to replace not found in file.,后面跟着那段对不上的文字。

没复现的两条(只按官方文档转述,别当成我们验证过):

  • 路径无法安全解析(worktree 隔离、软链接目标里带 ..):需要在 worktree 会话里测,我们没做。
  • permissions.blockWritesOutsideWorkingDirectories:我们在 2.1.312 的项目 settings 里设置后,用 bypassPermissions 写目录外的文件仍然成功了,没有被拦。官方文档写明,这个设置需要 Claude Code v2.1.314 或更新版本。我们没有换更新的版本,也没有试放进用户级 settings,所以不能说这条设置无效,只能说我们没复现。它的详细用法见 /permissions 和 blockWritesOutsideWorkingDirectories。

对症的改法

1. 非 UTF-8 文件

  • 想继续让 Claude 用 Edit 改:先备份,再转码。GBK 转 UTF-8:
cp gbk.txt gbk.txt.bak
iconv -f GBK -t UTF-8 gbk.txt.bak > gbk.txt
  • 转之前想一想:别的程序(老的构建脚本、Windows 下的旧工具)是不是还指望这个文件是 GBK。是的话就别转,让 Claude 按报错里说的用 shell 命令按原编码改。
  • 官方文档提醒:一个本应是 UTF-8 的文件,只要里面有一处非法字节序列,也会被同样拒绝。

2. Read deny 规则

  • 想让 Claude 改这个文件:在 /permissions 或 settings 里收窄、删掉那条 Read deny。
  • 文件必须保持不动:规则留着,再给同一路径加一条 Edit deny,这样 NotebookEdit 也被挡住(官方文档的建议)。

3. 软链接

照报错提示,让 Claude 改链接指向的真实文件。仓库里提交了带 .. 的软链接(比如 docs/current -> ../README.md)时,官方文档也建议直接改真实路径。

4. 没先读、文字对不上

这两条都是「Claude 的认知和磁盘上的文件不一致」。最稳的办法是让它重新读一遍文件再改;如果同一文件反复出现,看看是不是有格式化工具、同步软件或别的会话在同时改这个文件。

5. 路径被拦、目录外写入

这类按官方文档处理:Claude 通常会自己换成报错里给出的真实路径重试;目录外写入被设置挡住时,用 /add-dir 加目录,或去掉那条设置。我们没复现,详细步骤见官方 Error reference 的 Tool errors 一节。

常见问题

为什么我在 -p 模式或脚本里看到的是另一句话?

-p 没有交互界面,工具的完整报错就在输出里。我们还见过一句 Claude requested permissions to write to /tmp/cct/outside.txt, but you haven't granted it yet.:没授权的目录外写入会这样直接失败。这不是文件的问题,加 --permission-mode 或 --allowedTools 之前先想清楚要放开什么。

升级 Claude Code 能解决吗?

只对「老版本把非 UTF-8 文件悄悄改坏」这一类有用(v2.1.296 起会拒绝)。其他几条是配置或文件本身的问题,升级不会变。

更多 Claude Code 报错

看 Claude Code 报错速查。版本太旧的 400 见 does not support this model,Git 的锁文件见 index.lock File exists。

留下你的想法

你的邮箱不会公开。