VS Code + Codex + Clash 代理排障笔记

1. 问题背景

本次排查的目标,是解决 VS CodeCodex 无法正常访问 chatgpt.com 的问题。

项目环境如下:

  • 操作系统:Windows
  • 编辑器:VS Code
  • 终端:PowerShell
  • 代理工具:Clash Verge
  • Clash 本地 HTTP 代理端口:7897

当时浏览器可以正常访问 https://chatgpt.com,但 VS Code 中的 Codex 仍然报网络错误。

2. 最初出现的错误

Codex 日志中出现了如下错误:

1
2
2026-05-30 18:57:44.114 [error] Error fetching error="TypeError: fetch failed" url=https://chatgpt.com/ces/v1/rgstr?...&ec=100
2026-05-30 18:57:44.114 [error] Error fetching error="TypeError: fetch failed" url=https://chatgpt.com/ces/v1/rgstr?...&ec=1

这个错误的关键信息是:

  • 访问目标是 https://chatgpt.com/...
  • 报错是 TypeError: fetch failed

这类报错通常说明:

  • 请求还没有进入正常的业务处理阶段
  • 失败更可能发生在网络层
  • 常见原因包括 DNS、代理、证书、网络封锁或应用没有走代理

3. 第一轮排查

3.1 检查 DNS

执行:

1
Resolve-DnsName chatgpt.com

从现象看,域名最终是可以解析出 IP 的,因此问题不在“完全无法解析域名”这一层。

3.2 检查 443 端口连通性

执行:

1
Test-NetConnection chatgpt.com -Port 443

输出中出现了:

1
TcpTestSucceeded : False

这说明:

  • chatgpt.com:443 的 TCP 连接失败
  • 当时应用走的是直连
  • 连接甚至还没有进入 HTTPS 正常交互阶段

3.3 检查代理环境变量

执行:

1
Get-ChildItem Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY

结果显示这些变量不存在。

这说明:

  • 当前终端没有设置代理环境变量
  • 很多 CLI/Node/扩展进程会因此尝试直连

3.4 检查 WinHTTP 代理

执行:

1
netsh winhttp show proxy

输出为:

1
直接访问(没有代理服务器)。

这进一步说明:

  • 系统层面的 WinHTTP 代理没有配置
  • 从终端和 Codex 的角度看,仍然更像是在直连外网

4. 第一阶段结论

当时已经可以基本判断:

  1. 浏览器可以访问 chatgpt.com
  2. VS Code / PowerShell / Codex 访问失败
  3. 终端没有代理环境变量
  4. WinHTTP 没有代理
  5. 直连 chatgpt.com:443 失败

因此最核心的根因是:

浏览器走了代理,但 VS Code / Codex 所在进程没有正确走 Clash 代理。

5. 通过环境变量验证代理链路

为了验证是不是“没有走代理”导致的问题,在当前 PowerShell 会话中临时设置了代理:

1
2
$env:HTTP_PROXY="http://127.0.0.1:7897"
$env:HTTPS_PROXY="http://127.0.0.1:7897"

然后执行:

1
curl.exe -I https://chatgpt.com

返回结果中出现了:

1
2
3
HTTP/1.1 200 Connection established
HTTP/1.1 403 Forbidden
Cf-Mitigated: challenge

这个结果非常关键。

5.1 200 Connection established 的含义

它说明:

  • 本地请求已经成功连接到 Clash 代理
  • Clash 已经帮助建立了到目标站点的 HTTPS 隧道
  • 也就是说,代理链路已经通了

5.2 403 Forbidden 的含义

它说明:

  • 请求已经到达 chatgpt.com
  • 但被 Cloudflare 当作非浏览器请求拦住了
  • 这不是“连不上”,而是“连到了,但不放行这个请求形式”

5.3 为什么浏览器能开,curl 却 403

因为浏览器有这些能力:

  • Cookie
  • JavaScript 执行环境
  • 浏览器指纹
  • Cloudflare 挑战应答能力

curl -I 只是一个非常“裸”的请求,经常会被站点挑战机制拦截。

因此:

  • curl 返回 403 不表示代理失败
  • 反而说明代理已经生效,网络路径是通的

6. Clash Verge 中 TUN 的对应名称

在 Clash Verge 界面里,没有直接看到 TUN Mode

后续确认:

  • Clash Verge 中对应的是 虚拟网卡模式

如果它是灰色的,通常说明:

  • 功能存在
  • 但驱动或初始化尚未完成
  • 可能需要点击旁边的扳手图标安装相关组件
  • 有时需要管理员权限

不过这次问题不一定非得依赖 TUN 才能解决,因为只要:

  • 系统代理 正常
  • HTTP_PROXY / HTTPS_PROXY 正常

就已经足以让很多终端和应用走代理。

7. 在 VS Code 中加入代理设置

为了让 VS Code 本体和部分扩展网络请求也能识别代理,在用户级 settings.json 中加入了:

1
2
3
4
5
{
"http.proxy": "http://127.0.0.1:7897",
"http.proxySupport": "on",
"workbench.colorTheme": "Visual Studio Light"
}

这一步的作用是:

  • 让 VS Code 自身和部分扩展优先通过这个 HTTP 代理访问网络

但需要特别注意:

这一步不等于终端里的 curl 一定也会走代理。

因为:

  • settings.json 主要影响 VS Code 和部分扩展
  • PowerShell 中的 curl.exe 是否走代理,更依赖环境变量

8. 为什么“重载窗口”后仍然失败

在最初配置完成后,VS Code 集成终端中的:

1
curl.exe -I https://chatgpt.com

依然失败,但默认单独打开的 PowerShell 已经成功。

这说明:

  • 独立 PowerShell 已经继承到新的代理环境变量
  • VS Code 集成终端所在的进程,可能仍然继承的是旧环境

这里的关键点是:

Reload Window 不等于完全重启 VS Code 进程。

也就是说:

  • 重载窗口只会刷新界面和扩展状态
  • 不一定会让整个 Code.exe 进程重新读取系统环境变量

9. 最终解决方法

9.1 通过 setx 写入用户环境变量

执行:

1
2
3
4
setx HTTP_PROXY "http://127.0.0.1:7897"
setx HTTPS_PROXY "http://127.0.0.1:7897"
setx ALL_PROXY "http://127.0.0.1:7897"
setx NO_PROXY "localhost,127.0.0.1"

如有兼容性需要,也可以同时写入小写版本:

1
2
3
4
setx http_proxy "http://127.0.0.1:7897"
setx https_proxy "http://127.0.0.1:7897"
setx all_proxy "http://127.0.0.1:7897"
setx no_proxy "localhost,127.0.0.1"

9.2 在 VS Code settings.json 中配置代理

加入:

1
2
"http.proxy": "http://127.0.0.1:7897",
"http.proxySupport": "on"

9.3 完全退出 VS Code,而不仅仅是 Reload Window

正确做法是:

  1. 关闭所有 VS Code 窗口
  2. 确认后台没有残留 Code.exe
  3. 重新启动 VS Code

这一步非常关键,因为只有新的进程才会重新继承系统环境变量。

10. 最终验证结果

在 VS Code 集成终端中,curl.exe -I https://chatgpt.com 最终已经成功。

这意味着:

  • VS Code 集成终端已经获得正确的代理配置
  • 终端出站请求已经能通过 Clash 转发
  • 原先 fetch failed 的核心根因已经排除

如果此时 Codex 不再报最初那种连接错误,就说明网络代理链路已经恢复正常。

11. 后续出现的一个 warning

之后又出现过一条警告:

1
2026-05-30 19:28:18.638 [warning] [IpcClient] Received broadcast but no handler is configured method=thread-read-state-changed

这条日志的含义更像是:

  • 扩展内部收到了一个“线程已读状态变化”的广播
  • 但当前这一侧没有注册处理器

如果功能本身正常,这类 warning 一般可以视为:

  • 非核心问题
  • 内部状态同步提示
  • 可暂时忽略

它和这次网络代理排障不是同一类问题。

12. 本次排障的核心经验

12.1 浏览器能访问,不代表 VS Code / Codex 一定能访问

浏览器可能使用了:

  • 系统代理
  • 浏览器扩展代理
  • Clash 接管

而 VS Code / PowerShell / Node 进程不一定自动复用这套代理路径。

12.2 fetch failed 首先要怀疑“有没有走代理”

尤其在以下条件同时出现时:

  • 浏览器能打开目标站点
  • CLI 工具连不上
  • Test-NetConnection ... -Port 443 失败
  • 代理环境变量为空

12.3 403 不一定是坏事

在使用 curl 测试 chatgpt.com 这类站点时:

  • 直连失败,说明网络或代理链路不通
  • 返回 403 且带 Cf-Mitigated: challenge,反而说明已经到站了

12.4 Reload Window 不等于彻底重启 VS Code

环境变量类问题,经常需要:

  • 全关 VS Code
  • 重新启动新进程

否则很容易出现:

  • 外部 PowerShell 已生效
  • VS Code 集成终端仍未生效

13. 建议保留的排查命令

后续如果再次遇到类似问题,可以优先执行下面这些命令:

1
2
3
4
5
Resolve-DnsName chatgpt.com
Test-NetConnection chatgpt.com -Port 443
Get-ChildItem Env:HTTP_PROXY,Env:HTTPS_PROXY,Env:ALL_PROXY,Env:NO_PROXY
netsh winhttp show proxy
curl.exe -I https://chatgpt.com

14. 一句话总结

这次问题的本质不是 Codex 本身损坏,而是:

浏览器能走 Clash,但 VS Code / Codex / 集成终端最初没有正确继承代理配置;在补齐代理环境变量、配置 VS Code 代理并彻底重启 VS Code 后,问题得到解决。