Others

让 Claude Code 通宵跑任务,却被版本限制卡了一整夜

1179 字约 4 分钟

摘要中转站要求 Claude Code 的版本必须满足它的限制,通宵跑的会话因为中途发布了新版本而卡住。排查发现自动更新被一个环境变量顺带关掉了,打开之后两天又被另一条版本上限的报错打脸。

我用的中转站对 Claude Code 的版本有要求,版本不够新,请求就发不过去。有一晚我想让一个会话一直跑到天亮,结果早上一看,它从半夜起就卡着没动。

原来是中途发布了新版本,我本地没有更新。后来我在另一个会话里也撞上了同样的限制,屏幕上是一行 400 错误,大意是你的 Claude Code 版本 2.1.301 低于要求的最低版本 2.1.302,请更新。通宵的会话没有崩溃,只是请求发不出去,就一直停在那里。

自动更新被关掉了

我让助手想想办法让本地自动更新。它先检查了本机的安装方式和更新设置,发现自动更新是被我自己关掉的,而且不止一处。

  • settings.json 里设了 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1。这个变量的本意是关掉非必要的网络流量,可它同时会把后台的自动更新器也关掉。
  • 另一个配置文件里,autoUpdates 也是 false。

我当时用的是 native 安装方式,每个版本放在单独的目录里,靠一个软链接指向当前版本。从目录的修改时间看,软链接是当天早上才更新的,那是我自己手动更新的。

打开了也救不了已经在跑的会话

即使把自动更新打开,还有一个限制,助手提前提醒了我。更新器只负责下载新版本并切换软链接,已经在运行的进程仍然是旧的二进制,只会提示“重启后生效”。所以想让会话跑一整夜,除非在版本过期时自动重启它。

助手为此设想了更完整的方案。一是用 systemd 的用户定时器,每 5 分钟执行一次 claude update。二是写一个跑通宵用的包装脚本,在 tmux 里启动会话并记下会话编号,让一个看门狗每隔几分钟检查两件事,当前版本和会话进程的版本是否不同,会话的记录文件是否已经好几分钟没有写入。两个条件同时满足才杀掉旧进程,用新版本执行 claude --resume 接着干。

我没有选这个方案。自动更新打开后,更新完重新开个会话就行,我对通宵跑的需求并不多。

把变量拆开

具体的改法很简单。先把 settings.json 和另一个配置文件备份到备份目录,然后做两件事。

  • 把 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 去掉,换成它所包含的另外几个变量,DISABLE_TELEMETRY、DISABLE_ERROR_REPORTING、DISABLE_BUG_COMMAND,这样遥测和错误上报仍然是关着的,只是不再顺带关掉自动更新。
  • 把 autoUpdates 从 false 改成 true。

检查的时候还有一个小插曲。改完以后 claude doctor 仍然显示自动更新是禁用的,原因是正在运行的这个进程,继承的还是旧的环境变量。换一个新会话再看,就显示启用了。

助手也如实提醒了这个办法的局限,更新器是 Claude Code 自己运行时去检查的,并不是系统级的定时任务。如果哪天夜里会话因为版本过期卡住了,早上重开时会先装上新版,但卡住的那段时间已经浪费了。

两天后,限制反过来了

这件事本来到这里就该结束了,但是两天后我又遇到了一行很相似的报错,这次说的是我的版本 2.1.303 超过了允许的最高版本 2.1.302,请降级。

原来中转站对版本的要求不是只有下限,而是一个范围,它先后加上了最低版本和最高版本。我刚打开的自动更新,恰好把本机升到了高于上限的版本。更巧的是,报错信息里建议的做法,是安装指定版本,并设置 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 来阻止自动升级,也就是我两天前刚刚去掉的那个变量。

现在我的配置里,自动更新又被关上了,版本靠自己手动升级。回头看,这件事的教训很简单。

先弄清楚上游对版本的约束

自动更新好不好,取决于上游对客户端版本是怎么约束的。只有下限的时候,自动更新是保险。有上限的时候,它反而是风险。动手之前最好先问清楚,上游是只要求“不低于”,还是要求一个范围。

如果你也在用中转站,遇到 400 并且提示版本,先看报错里写的是 minimum 还是 maximum,两个方向的处理办法正好相反。

评论