凌晨 03:18,一台 Debian 13 的機器斷了網。03:22,自動更新器還是跑了一次 npm update。

這是 2026 年 10 月 11 日有人在 anthropics/claude-code 開的 issue #101150,標題長這樣:

npm auto-update during network outage replaces working install with 500-byte stub

原文來源:anthropics/claude-code#101150

內文很短。更新完,bin/claude.exe 變成一支 500 byte 的占位腳本,訊息是 “Error: claude native binary not installed”,權限 664,所以執行 claude 只剩 Permission denied。回報者接著寫:Remote Control 也連不上,這台機器沒辦法遠端救回來,claude 得等人手動把 package 重裝才能用。環境是 npm global install、更新到 2.1.296、Linux x86_64。

我沒有重現這張單,也不知道它最後怎麼收。但它讓我想弄清楚一件事:「別讓 Claude Code 自己更新」這種需求,現在到底有幾個設定在管,為什麼會有這麼多個?答案散在十幾個版本的 CHANGELOG 裡,所以我照時間一條一條排。

先交代日期怎麼來的。CHANGELOG 本身不帶日期,下面每個日期都是那個版本在 npm 的上架時間(UTC),我用 npm view @anthropic-ai/claude-code time --json 查的。原文引自 CHANGELOG,行為描述引自官方 Set up Claude Code 與 managed settings 頁。

2025 年 11 月:開關本身先要修對

最早能在 CHANGELOG 裡找到的相關條目是 2.0.36,npm 上架時間 2025-11-07:

Fixed: DISABLE_AUTOUPDATER environment variable now properly disables package manager update notifications

注意這是 Fixed,不是 Added。DISABLE_AUTOUPDATER 最早哪一版加進來,我用關鍵字在 CHANGELOG 搜不到「Added」的條目,所以不知道,這裡不猜。能確定的只有:到 2.0.36,這個環境變數已經存在,而且關掉自動更新之後,套件管理器的更新通知還是會冒出來,直到這版才修掉。

2026 年 1 月:通道出現,而且開始看得見

2.1.3(2026-01-09):

Added release channel (stable or latest) toggle to /config

四天後的 2.1.6(2026-01-13)加了讓人看見它的地方:

Added Updates section to /doctor showing auto-update channel and available npm versions (stable/latest)

再過八天,2.1.15(2026-01-21)給 npm 安裝加了一則棄用通知,叫人跑 claude install。

通道到底是什麼?官方的說法是 latest 是預設,新功能一出就收到;stable 則是「typically about one week old, skipping releases with major regressions」,通常慢大約一週,並跳過有重大退步的版本。我的比喻是訂報紙,早報最快,但印錯的機率也最高;晚報慢一點,明顯的錯多半已經被編輯改掉了。要用哪份,在 settings.json 寫一行:

1
2
3
{
"autoUpdatesChannel": "stable"
}

出處:Set up Claude Code,Update Claude Code 一節,官方範例原樣

這裡有個官方自己寫出來的代價:新發表的模型可能需要比 stable 通道所提供的更新的 Claude Code 版本,想立刻用就得換回 latest。穩,是用「晚一點拿到」換的。

CHANGELOG 只寫加了什麼,不寫為什麼加。通道為什麼在 2026 年 1 月出現,是誰被哪次更新坑過,我讀不到。

2026 年 4 月:關掉了,手動指令還是能更新

這一段我覺得最有意思,因為三個版本都落在「更新該不該發生」的邊角上。

2.1.92(2026-04-04)修的是 Homebrew:安裝後的更新提示改成跟著 cask 的通道走,claude-code 對應 stable,claude-code@latest 對應 latest。

2.1.98(2026-04-09)是這樣:

Fixed DISABLE_AUTOUPDATER not fully suppressing the npm registry version check and symlink modification on npm-based installs

白話一點:有人設了 DISABLE_AUTOUPDATER,npm 安裝還是會去查 registry 的版本,還會動 symlink。這是一條真實的死路,設了開關,以為關乾淨了,其實沒有。環境變數設進去,不等於關乾淨了,要確認它到底關到哪一層。

2.1.118(2026-04-22):

Added DISABLE_UPDATES env var to completely block all update paths including manual claude update — stricter than DISABLE_AUTOUPDATER

官方 setup 頁把差別講得很白:DISABLE_AUTOUPDATER 只停背景檢查,claude update 和 claude install 照樣能用;要連手動更新一起擋,改設 DISABLE_UPDATES。它的使用情境也寫了,是你自己經由內部管道發佈 Claude Code,需要使用者停在你給的版本。背景更新的開關,官方範例是這樣寫的:

1
2
3
4
5
{
"env": {
"DISABLE_AUTOUPDATER": "1"
}
}

出處:同上 setup 頁,官方範例原樣。這個只停背景更新;要擋手動更新的是 DISABLE_UPDATES,頁面上沒有給它的 JSON 範例,所以我不自己寫一份冒充官方的。

順帶一個驗證方式,也是官方寫的:跑 claude doctor,看 Auto-updates 那行是不是顯示 disabled (set by env: DISABLE_AUTOUPDATER) 而不是 enabled。我沒有跑過,只是轉述。

2026 年 5 月到 6 月:從「不要更新」走到「不准啟動」

2.1.153(2026-05-27)有兩條。一條是 npm 全域安裝無法自動更新時,會跳一次性通知,/doctor 列出修法。另一條修了 claude update 在 npm 安裝下裝成最新版、沒有照設定的通道走。

然後是 2.1.163(2026-06-04):

Added requiredMinimumVersion and requiredMaximumVersion managed settings — Claude Code refuses to start if its version is outside the allowed range and directs the user to an approved version

前面所有設定管的都是「更新」這個動作:什麼時候更新、更新到哪、能不能更新。這兩個管的是另一件事,啟動。版本在範圍外,Claude Code 乾脆不啟動,並指向一個核准的版本。

這時候四個東西各自管的範圍,我必須分清楚,因為它們名字很像,管的卻不一樣:

autoUpdatesChannel 決定更新「看哪一條通道」。minimumVersion 是更新的地板:官方寫背景自動更新和 claude update 都拒絕裝比它低的版本,所以你已經在 latest 的新版上、才切去 stable 的話,不會被降級;從 latest 切到 stable 時 /config 會問你要留在目前版本還是允許降級,選留下就會把 minimumVersion 設成目前的版本,切回 latest 會清掉它。DISABLE_UPDATES 是完全封鎖。而 requiredMinimumVersion/requiredMaximumVersion 是門禁,而且是 managed setting。

官方有一句話把地板和門禁切開:

The minimumVersion pin only constrains updates. To make Claude Code refuse to start outside a version range, use the managed settings requiredMinimumVersion and requiredMaximumVersion instead. Updates also respect the requiredMaximumVersion ceiling.

也就是說,地板只約束更新,不約束啟動;要擋啟動得用門禁。門禁還有兩個細節,managed settings 那頁寫的:它擋的是「過舊的 binary 啟動」,不會把已經在跑的 session 結束;而且是 fail open,值無效時會被丟掉、不強制執行。下發的機制我之前寫過,在 沒有 MDM,公司的規則怎麼跑到那台筆電上,這篇不重複。

地板的寫法,官方範例是通道加下限放在一起:

1
2
3
4
{
"autoUpdatesChannel": "stable",
"minimumVersion": "2.1.100"
}

出處:同上 setup 頁,官方範例原樣

至於 minimumVersion 這個設定是哪一版加進來的,我一樣查不到 Added 條目,只能說 2.1.277 的 CHANGELOG 證明它在那之前已經存在。

2026 年 9 月到 10 月:開始補更新器自己的洞

這一段跟前面不同。前面多半是加設定,這裡是修更新器本身。

2.1.277(2026-09-18)修的是:代理伺服器回傳無效版本時,更新檢查每 30 分鐘報一次錯,以及設了最低或最高版本時 claude update 會卡住;同一條還寫了格式錯誤的 minimumVersion 現在會被忽略。

2.1.288(2026-10-02):

Fixed the npm auto-updater reporting success when the platform-native binary failed to download and only the placeholder claude stub was installed

2.1.295(2026-10-08)修了在 /config 改自動更新通道時,儲存發生在 plugin 的 config.set hook 被詢問之前。

2.1.288 那條,讀起來跟開頭 #101150 很像:binary 沒下載成功,只剩占位的 claude stub,更新器卻回報成功。但 #101150 的回報版本是 2.1.296,比 2.1.288 晚。兩者是不是同一個根因,我沒有查,所以我不會說「2.1.288 修好了」,也不會說「沒修好」。這個問題我答不出來。

我的立場,以及什麼會讓我改

如果是一台無人值守、斷網也沒人救得回來的機器,我會選 DISABLE_UPDATES,不選 DISABLE_AUTOUPDATER,更新改成人在場時手動做。理由是 4 月那兩條:只設 DISABLE_AUTOUPDATER,手動路徑還開著,npm 安裝在 2.1.98 之前連查版本與動 symlink 都沒關乾淨;2.1.118 才有連手動更新也擋的開關。通道選 stable 也救不了這件事,因為官方說的是跳過「重大退步」的版本,不是保證更新過程不會中斷。

會讓我改主意的條件有兩個:一是 #101150 確認是個已修好的舊 bug,二是這台機器有人定期登入、斷網能自己處理。那時候讓它自己更新的成本,就低於漏掉修正版本的成本。

我只讀了文件與 issue,沒有實際跑過任何一條更新指令,也沒有重現過 #101150。上面所有行為描述,都是官方文件與 CHANGELOG 的轉述。

我讀到 #101150 的時候,它仍然是 OPEN。那四分鐘裡,更新器是在哪一步把舊 binary 換成了 stub,我讀到的內文沒寫,CHANGELOG 也沒寫。能確定的是官方文件寫明的兩個缺口:DISABLE_AUTOUPDATER 只停背景檢查,要連手動更新一起擋得用 DISABLE_UPDATES;minimumVersion 只約束更新,要擋啟動得用 requiredMinimumVersion。