在 Windows 上通过 git-bash(MSYS2)运行工具时,MSYS2 路径格式 /c/Projects 会被 Windows 原生工具误读为 C:\c\Projects,导致文件"消失"。文章给出三层修复方案。
文件在 Windows 机器上凭空消失,而你又在通过 git-bash 运行 Hermes(或其他工具)?先查一下有没有一个叫 C:\c 的文件夹。如果有,那就是遇到了 MSYS2 幻影路径 bug——你以为自己保存的文件其实一直写到了这个鬼目录里。下面来解释发生了什么,以及我这段时间一直在用的三层修复方案。
Hermes Agent 在 Windows 上运行于 git-bash(MSYS2)终端环境中。这产生了一个持续性的路径转换问题:
当 Agent 或某个工具使用 MSYS2 规范构造路径(如 /c/Projects/data.txt),原生 Windows 工具(Python 的 open()、write_file 工具、FileSystem MCP 操作)会字面解释这个路径,导致生成 C:\c\Projects\data.txt 而不是预期的 C:\Projects\data.txt。
文件"消失"——写到了一个幻影 C:\c\... 目录而非预期位置
Agent 报告"路径未找到"或"文件已创建",但文件不在预期位置
系统上出现一个幻影 C:\c 目录,积累了大量孤儿文件
子 Agent 丢失工作成果,因为写到了错误位置
构建输出到了意外的地方,浪费开发时间
Hermes Desktop for Windows 使用 git-bash 作为终端后端,而 git-bash 建立在 MSYS2 之上。MSYS2 提供了一个 POSIX 兼容层,包含自动路径转换:它在将参数传递给原生 Windows 程序时会将 /c/ 转换为 C:\。然而,这种转换只在路径经过 MSYS2 的参数处理时才会生效。当路径字符串直接嵌入到 Python 脚本、MCP 工具调用或 Hermes 原生工具(如 write_file 或 FileSystem)中时,根本不会经过 MSYS2 转换,字面的 /c/ 前缀就变成了根目录 C:\ 下名为 c 的目录。
此问题影响 Hermes Agent v0.19 及之前所有 Windows 版本。后续版本可能在框架层面解决这个问题,但在那之前这个变通方案仍然适用。
这是一个两种执行上下文之间的路径格式不匹配:
bug 触发的条件是:POSIX 风格路径(/c/...)被传给了非 MSYS2 上下文。MSYS2 参数转换层(MSYS2_ARG_CONV_EXCL)只处理在 shell 层面传递给子进程的参数;它不会影响 Python 的 os.path 模块或 Windows API 调用如何解析字符串。
我运行三层独立的防御。每层捕获上一层遗漏的问题。
作用:在从 bash 生成原生 Windows 子进程时,防止 MSYS2 转换 /c/... 路径。
要编辑的文件:~/.bashrc(或对应的 git-bash 配置文件)
# ===== MSYS2 PATH FIX =====
# Prevent MSYS2 from mangling /c/... paths into C:\c\...
# Without this, /c/Projects can be misinterpreted as C:\c\Projects
# causing phantom directories and lost files.
export MSYS2_ARG_CONV_EXCL="*"
export MSYS_NO_PATHCONV=1
为何这只是部分修复:这只影响 MSYS2 在生成子进程时处理参数的方式。MSYS2 原生二进制文件(bash、mkdir、git、cp 等)继续通过自己的挂载表正确解析 /c/...。但它无法修复路径字符串直接嵌入 Python 代码或 Hermes 工具参数的情况——那些上下文压根没有经过 MSYS2 参数处理。
编辑后,重启 git-bash 或加载配置文件:
source ~/.bashrc
编辑前务必备份:
cp ~/.bashrc ~/.bashrc.bak
作用:预创建 C:\c 目录,并为其设置 Deny Write 访问控制条目。如果第一层失败或某个路径漏了过去,任何写入 C:\c\... 的尝试都会收到明确的 Access Denied 错误,而不是静默创建幻影目录。
实现(在 PowerShell 中以管理员身份运行):
# Create the phantom directory if it doesn't exist
if (-not (Test-Path "C:\c")) {
New-Item -Path "C:\c" -ItemType Directory -Force
}
# Set Deny Write + Deny Delete Child for Everyone
icacls C:\c /deny "Everyone:(W,DC)"
# Verify
icacls C:\c
# This should fail with "Access Denied"
New-Item -Path "C:\c\test-block.txt" -ItemType File
为何这一层是关键:Access Denied 错误不可能被忽略。当某个工具或子 Agent 收到这个错误,这就是一个清晰信号,说明路径有问题。对比原来的行为:在错误位置静默创建文件,可能几个小时都不会被发现。
作用:通过持久化记忆(MEMORY.md 或 SOUL.md)训练 Agent 识别 Access Denied 信号并修复路径。
Memory/SOUL 条目:
TRIGGER (MSYS2 phantom path): When ANY tool or command errors with
"Access Denied", "Permission denied", "No such file or directory",
or "file not found" on a path containing `C:\c\...`, `C:/c/...`,
or `/c/c/...` — this is the MSYS2 path conversion bug.
IMMEDIATE FIX:
1. Replace the MSYS2-style prefix `/c/...` or the phantom `C:\c\...`
with the correct Windows-native prefix `C:\` or `C:/`
2. Retry the operation with the corrected path
3. Do NOT manually delete or modify the C:\c directory — it is the
guardrail and must remain in place
The root cause is passing a POSIX /c/ path to a native Windows tool
or Hermes native tool (write_file, FileSystem, read_file) that doesn't
understand MSYS2 mount table resolution. The Deny ACL on C:\c exists
specifically to catch this with a visible error.
NEXT ACTION: Always retry with a C:/ path after seeing this error.
错误触发时的 Agent 工作流:
Tool call → "Access Denied on C:\c\Projects\..."
→ Agent memory triggers recognition
→ Agent identifies: path contains C:\c\ — MSYS2 phantom bug
→ Agent rewrites path: "/c/Projects/..." → "C:/Projects/..."
→ Agent retries with corrected path
→ Operation succeeds
实现全部三层后,运行以下测试:
测试 1:终端路径解析(第一层)
mkdir -p /c/Projects/msys2-verify
echo "test" > /c/Projects/msys2-verify/test.txt
ls -la /c/Projects/msys2-verify/
# Should show test.txt
测试 2:清理测试产物
rm -rf /c/Projects/msys2-verify
测试 3:幻影路径被拦截(第二层)
# Should fail: "Access Denied"
New-Item -Path "C:\c\verify-test.txt" -ItemType File
测试 4:不存在幻影文件
Get-ChildItem "C:\c" -Force
# Should return empty (or nothing)
撤销第一层(环境变量):从 ~/.bashrc 中删除那两行,然后重启 git-bash。
撤销第二层(护栏 ACL):
icacls C:\c /remove:d Everyone
icacls C:\c /grant "Everyone:(W)"
# Or remove the directory entirely (after confirming it's empty):
rmdir C:\c
撤销第三层(Agent 记忆):从 MEMORY.md / SOUL.md 中删除或注释掉触发条目。
此问题源于 Hermes Agent 在 Windows 上使用 git-bash(MSYS2)作为终端后端。Hermes 的未来版本可能会:
切换到不使用 MSYS2 路径转换的原生 Windows 终端(PowerShell Core 或 Windows Terminal)
在将 /c/... 路径传递给原生工具之前,自动将其规范化为 C:/...
提供一个内置路径验证器,在工具参数中捕获 MSYS2 路径
在那之前,这套三层方案对我来说一直运行良好。第二层才是关键:它是系统级保护,所以无论 Agent 是否记得修复方案,它都能生效。操作系统直接拒绝。
完整文档(含每条命令和验证测试)见我的 hermes-kb-hack-fix 仓库,里面还有我遇到的其他几个 Windows 和 Hermes 坑。如果你也被神秘的 C:\c 文件夹坑丢了文件,可以试试这个方案。