1. Windows 下 Claude Code 报 Exit Code 1 到底卡在哪
如果你在 Windows 上用 Claude Code,大概率见过这个场景:让它跑一条npm run build或者git status,界面转了两秒,然后甩给你一句Exit Code 1,没有报错堆栈,没有输出内容,命令像是执行了又像是没执行。更迷惑的是,同样的命令你手动在 Git Bash 里敲一遍,完全正常。这个Exit Code 1不是 Claude Code 本身崩了,而是它调用 shell 的那条链路断了——它启动了一个进程,但没能从标准输出/标准错误里读到任何东西,于是只能判定“命令失败”。
这个问题的核心检索词就是CLAUDE_CODE_GIT_BASH_PATH、bash.exe、git-bash.exe。Claude Code 在 Windows 上并不直接使用 cmd 或 PowerShell 作为命令执行后端,它需要一个 POSIX 风格的 shell 来跑工具链,官方选择的是 Git for Windows 自带的 bash。而CLAUDE_CODE_GIT_BASH_PATH这个环境变量,就是告诉 Claude Code“去哪里找这个 bash”。一旦它指向了错误的可执行文件,命令执行就会静默失败,表现为Exit Code 1。
适合谁看:在 Windows 10/11 上装了 Claude Code、装了 Git for Windows、但一让 AI 执行命令就报 Exit Code 1 的开发者。整篇会从环境变量配置讲到settings.json骨架,再到逐条验证动作,最后把常见坑一次性排掉。你不需要重装系统,也不需要换终端,改对一个路径就能恢复。
2. 前置准备:确认 Git Bash 与 TaoToken 接入环境
在动手改路径之前,先把两个前提确认掉,否则后面排查会互相干扰。
第一,确认 Git for Windows 已经正确安装。打开文件资源管理器,进到C:\Program Files\Git\bin\,你应该能看到bash.exe。同时C:\Program Files\Git\根目录下会有git-bash.exe。这两个文件长得像,但角色完全不同:bash.exe是真正的 shell 可执行文件,git-bash.exe是一个启动器,它会拉起一个带图形窗口的终端。Claude Code 需要的是前者,因为它要的是标准输入输出流,而不是一个窗口。
第二,确认你的模型接入侧是通的。Claude Code 只是客户端,它执行命令失败和模型请求失败是两码事。如果你还没配好接入,可以先去 TaoToken 官网 https://taotoken.net/?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 看一下接入说明,API 入口是 https://taotoken.net/api。拿到 key 之后,在 Claude Code 里配置好 base_url 和 api_key,确保模型对话本身是正常的。这样当Exit Code 1出现时,你能确定问题出在 shell 调用,而不是网络或鉴权。
注意:不要把
CLAUDE_CODE_GIT_BASH_PATH指向git-bash.exe。这是网上很多教程的误导点,也是本篇要重点纠正的地方。
3. 可复制配置:settings.json 骨架与环境变量写法
Claude Code 在 Windows 上的配置分两层:一层是系统环境变量,一层是项目或用户级的settings.json。环境变量负责告诉客户端 bash 在哪,settings.json负责权限、工具开关等行为。下面给出可直接复制的骨架。
先看环境变量。在 PowerShell 里临时设置(当前会话有效):
$env:CLAUDE_CODE_GIT_BASH_PATH = "C:\Program Files\Git\bin\bash.exe"如果要永久生效,用系统属性里的“环境变量”面板新建一条用户变量,变量名CLAUDE_CODE_GIT_BASH_PATH,变量值C:\Program Files\Git\bin\bash.exe。注意路径里不要加引号,也不要用正斜杠混写,Windows 下反斜杠即可。
再看settings.json。Claude Code 的用户级配置一般放在%USERPROFILE%\.claude\settings.json,项目级放在项目根目录的.claude\settings.json。一个可用的骨架如下:
{ "env": { "CLAUDE_CODE_GIT_BASH_PATH": "C:\\Program Files\\Git\\bin\\bash.exe" }, "permissions": { "allow": [ "Bash(git status)", "Bash(git diff:*)", "Bash(npm run:*)" ], "deny": [] } }这里有个细节:JSON 里的反斜杠必须转义成\\,否则解析会出错。如果你在settings.json里写路径,务必用双反斜杠。permissions.allow里列的是允许自动执行的命令前缀,Bash(git diff:*)表示允许所有以git diff开头的命令。这个列表按你的实际工作流增减,不要一上来就全放开。
配置改完后,完全退出 Claude Code 再重新启动,环境变量和 settings 才会重新加载。
4. 逐条验证:从 echo 到真实命令的成功结果
配置写完不代表生效,必须逐条验证。下面这套动作按顺序做,每一步都有明确的预期结果。
第一步,验证环境变量是否被读到。在 Claude Code 里让它执行:
echo $CLAUDE_CODE_GIT_BASH_PATH预期输出是/c/Program Files/Git/bin/bash.exe或者 Windows 风格路径。如果输出为空,说明环境变量没生效,回到上一步检查变量名拼写和是否重启了客户端。
第二步,验证 bash 本身能被调用。执行:
bash --version预期看到GNU bash, version 5.x.x之类的版本信息。如果这一步就报Exit Code 1,说明CLAUDE_CODE_GIT_BASH_PATH指向的文件根本不存在或不可执行。
第三步,验证标准输出能被捕获。执行:
echo "hello from bash"预期输出hello from bash。这一步是关键分水岭:如果前两步正常但这一步没输出,说明 shell 启动了但输出流没接上,通常就是指向了git-bash.exe导致的。
第四步,跑一条真实项目命令。进到你的项目目录,执行:
git status预期看到当前分支、修改文件列表。如果这里正常返回,说明整条链路已经通了,之前的Exit Code 1应该消失。
第五步,验证错误流也能被捕获。执行一条故意失败的命令:
ls /nonexistent-path-xyz预期看到No such file or directory这样的错误信息,而不是空白的Exit Code 1。能读到错误信息,说明 stderr 也正常传递了。
这五步走完,基本可以确认修复成功。如果某一步卡住,对照下一节的排查表。
5. 本篇常见错排查:路径、转义、权限与缓存
即使照着做,也可能踩到一些边角问题。下面按现象归类。
现象一:改了环境变量但 Claude Code 里echo还是空。原因通常是客户端没完全退出,或者你在 IDE 插件里用的 Claude Code 继承了 IDE 的环境而不是系统环境。解决办法是彻底关闭 IDE 和所有 Claude Code 进程,再从新的终端启动。
现象二:settings.json保存后客户端启动报解析错误。九成是路径转义问题。JSON 里C:\Program Files必须写成C:\\Program Files。如果你不确定,干脆在settings.json里不写这个 env,只用系统环境变量,避免双重配置冲突。
现象三:bash --version能跑,但git status报Exit Code 1且无输出。这通常是工作目录不对,Claude Code 在一个非 Git 仓库的目录里执行了 git 命令。让它先pwd确认当前目录,再cd到正确项目路径。
现象四:路径里有空格导致调用失败。C:\Program Files\Git\bin\bash.exe带空格,某些旧版本客户端在拼接命令时没做引号处理。确认你用的是较新版本的 Claude Code,旧版本建议升级。
现象五:装了多个 Git(比如系统级 + 便携版),环境变量指向了被删除的那个。用where bash在 PowerShell 里查一下实际存在的 bash 路径,以那个为准。
现象六:权限被settings.json的 deny 规则挡住。如果你在permissions.deny里写了过宽的规则,命令会被拦截并可能表现为失败。检查 deny 列表,临时清空测试。
提示:排查时优先用
echo和bash --version这种无副作用命令,不要一上来就跑构建脚本,否则错误信息会被构建日志淹没。
6. 接入与排障分流:把 key、文档和模型对话用起来
命令执行链路修好之后,接下来就是把模型接入侧也理顺。如果你在配置 base_url 或 api_key 时遇到问题,直接去 API Keys 页面生成和管理密钥:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。接入文档在 https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,里面有各客户端的配置示例,照着填即可。
想先验证模型本身是否正常,可以用模型对话页面发一条测试消息:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= 。如果对话正常但 Claude Code 里命令执行失败,那问题一定在 shell 配置,回到第 3、4 节。
如果你打算长期用 Claude Code 做编码和 Agent 任务,建议了解一下 Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,它针对高频编码场景做了额度规划,比按次调用更省心。控制台入口在 https://taotoken.net/console?utm_source=taotoken_aicg_blog_end&utm_medium=csdn&utm_campaign=rewrite&utm_content= ,可以查看用量和调用记录。
最后补一个我自己的习惯:每次改完CLAUDE_CODE_GIT_BASH_PATH,我都会先让 Claude Code 跑一遍bash --version && echo ok && git status,三条命令串起来一次验证。只要这三条都正常返回,后面让它跑构建、跑测试基本不会再出Exit Code 1。路径这东西,改对一次,后面就一劳永逸了。