登入到期的三個數字:3 天、10 天、一年,claude -p 腳本會死在哪一個
authentication 頁說,登入到期前 3 天,啟動時會警告。2.1.318 的 changelog 說,claude -p 從到期前 10 天起就多印一行 stderr 警告。兩個數字出自不同頁面,文件沒有把它們接起來。
那支定時在凌晨跑的 claude -p 腳本,會先撞上哪一個?它停之前,又有誰在哪個地方提醒過你?這個情境是我假設的,不是別人回報的案例,也不是我遇過的。我會去翻文件,是因為 2.1.318 的 changelog 一口氣補了好幾條跟登入到期有關的東西,翻完才發現「提前幾天提醒」的數字對不上。
先交代版本與日期。npm registry 顯示 2.1.318 的發布時間是 2026-11-03 21:55:17 UTC,changelog 頁把同一版標成 November 4, 2026;2.1.317 在 npm 是 2026-11-02 23:57:53 UTC,changelog 標 November 3, 2026。兩邊差一天,我沒查出原因,下面引用日期時都寫 changelog 標的那個,並註明。
到期的那一刻,Claude Code 到底做了什麼
errors 頁的 Login expired 那一段,描述了登入失效時的一種情況,寫得很具體:Claude Code 試著更新你存下來的 claude.ai 登入,OAuth 服務拒絕了存著的 refresh token,於是 Claude Code 把存著的憑證清掉。之後每一次模型請求,都在本機就被這則訊息擋下來,根本到不了 API,因為只有 /login 能建立新憑證。
互動畫面看到的是 Login expired · Please run /login。在 -p 與 Agent SDK 裡,文字變成 Failed to authenticate: OAuth session expired and could not be refreshed,錯誤碼是 authentication_failed。文件給的處理很樸素:非互動模式下,在同一個環境跑 claude、完成 /login,再重跑指令;沒辦法互動登入的自動化,改用 ANTHROPIC_API_KEY,或用 claude setup-token 產一個長效 token。
照這一段讀,失效不是「時間到了,下一次請求被拒」,是「更新失敗,憑證被清掉,之後全部本機擋下」。它跟 changelog 說的「到期」是不是同一件事,文件沒接起來,下一段會再提。
2.1.318 另外有一條修正,提到「a stored claude.ai login reaches its time limit」的登入失敗,現在會明講原因,而且在 claude -p 裡會點名 claude auth login 與 claude setup-token。這個 time limit 跟上面 refresh token 被拒是不是同一條路,文件沒說,我不猜。
三個數字並排
提醒分散在三個地方。我把原文的數字、出現位置、出處與沒寫的部分放進同一張表,因為它們散在不同頁,單看任何一頁都湊不齊:
| 數字 | 出現位置 | 出處 | 文件沒寫的 | |
|---|---|---|---|---|
| 互動式啟動警告 | 到期前 3 天內 | 啟動時,針對 /login 建立的登入 |
authentication 頁 | 是否也適用 -p |
-p 的 stderr 警告 |
到期前 10 天起 | claude -p 的 text 輸出,一行 |
2.1.318 changelog | 跟 3 天是否同一種憑證 |
setup-token 的 token |
一年期 | CLAUDE_CODE_OAUTH_TOKEN 環境變數 |
authentication 頁 | 快到期有沒有警告 |
這是我整理的表,不是文件原有的。第三列嚴格說算壽命,不算提醒,放進來因為它決定了你會不會落到前兩列。
本篇所有行為都只讀文件,沒有登入、沒有跑過 claude auth status、沒有跑過 claude -p。我沒看過警告實際印出來的字樣、loginExpiresAt 的值是日期字串還是別的格式,也不知道自己本機的登入還剩幾天。本機唯一跑過的是 claude --version(印出 2.1.318)與 claude auth status --help,後者的選項只有 --json 與 --text,說明裡沒提到到期日。
3 天:文件寫的是互動式啟動
authentication 頁有一個小節叫 Renew an expiring login。原文:用 /login 建立的登入在到期前三天內,Claude Code 啟動時顯示警告:Your login expires in 3 days · run /login to renew。
這個警告不擋請求,到期之前驗證照常運作。它只在 claude.ai 登入是目前使用的憑證時才出現;憑證若由雲端供應商、ANTHROPIC_API_KEY、ANTHROPIC_AUTH_TOKEN 或 apiKeyHelper 供應,就不會有。
文件特別點出一種受害者:無人看守的 session。agent view 的背景 session,或 Remote Control session,如果比登入活得久,憑證一到期就停止前進,要等你重新登入才救得回來。另外 /status 有一列 Login,到期後會顯示 Expired — log in again,連同它存下的組織與 email,需要 v2.1.210 以上。
注意這一整段都是「啟動時」。一支每天凌晨跑一次的腳本,每次都是新啟動沒錯,可是啟動警告出現在哪個輸出、有沒有人看,文件沒有談。
10 天:只在 changelog 出現的那一組
2.1.318 的 changelog(標 November 4, 2026)在 Added 底下有兩條。第一條是把 stored claude.ai sign-in 的結束日期加進 claude auth status(欄位叫 loginExpiresAt)與 claude -p 的 JSON 結果(欄位叫 credential_expires_at)。第二條是 claude -p 的 text 輸出,從 stored claude.ai sign-in 結束前 10 天開始,多一行 stderr 警告。
我去對其他頁,結果是這樣:
cli-reference 頁寫 claude auth status 的那一列,說它輸出 JSON、--text 給人讀、已登入 exit 0 否則 exit 1、JSON 含 configDirectory(v2.1.268 以上)與 authMethod,沒提到 loginExpiresAt。headless 頁通篇讀完,沒有 credential_expires_at,也沒有到期警告的段落;--output-format json 那段只說是含 result、session ID 與 metadata 的結構化 JSON,沒有欄位表。authentication 頁沒提到 10 天,也沒提到 claude -p 的 stderr 警告。errors 頁我只讀到前 200,000 字元(全頁約 609,486 字元),同樣沒見到。Agent SDK 的 TypeScript 頁只讀了前 100,000 字元,約佔全頁 331,022 字元的三成,結果欄位表在哪我沒讀到。
所以 loginExpiresAt 與 credential_expires_at 目前我只在 changelog 看過。欄位長什麼格式、API key 登入時有沒有這個欄位,都沒有證據。
3 天對 10 天,我不裁決
兩個數字擺在一起,最自然的讀法是「一個是舊的、一個是新的」,或「一個管互動、一個管 -p」。但文件沒有這樣說。authentication 頁沒提 10 天,changelog 沒提 3 天,兩邊也沒寫它們是不是同一種憑證、為什麼數字不同。我手上的資料只能支持並列,不能支持任何一種解釋。
這裡有一個我覺得值得單獨記下來的細節:2.1.317 的 changelog 寫,修了 claude auth status 在慢速 token refresh 還沒存完就退出,可能害你下次執行時被登出。就是說,一個聽起來只是「看狀態」的指令,在某些情況下會碰到 token refresh。具體什麼條件會刷新、有沒有寫檔,文件沒細節。這也是這篇沒有執行 claude auth status 的原因:它可能觸發刷新與寫檔,我不確定它是不是純讀取。2.1.318 同一批還有兩條相近的修正:claude plugin 指令在慢速 token refresh 存完前退出,可能害你下次被登出;以及另一個終端機或主機用同一帳號與組織、在同一個 home 重新登入時,工作會以 Not logged in 結束。errors 頁對後者的說法是,v2.1.318 之前,重新登入的過程會先移除舊登入、才存新的。
一年:setup-token 落在哪
authentication 頁說,CI、腳本這類沒辦法互動登入的環境,可以用 claude setup-token 產一個一年期的 OAuth token。它不會幫你存,印在終端機上,由你自己設成 CLAUDE_CODE_OAUTH_TOKEN 環境變數。限制也寫了:只能發模型請求,建不了 Remote Control session,也抓不到 claude.ai connectors;bare mode 不讀 CLAUDE_CODE_OAUTH_TOKEN。cli-reference 那一列補了一句,需要 Claude 訂閱。
驗證優先序裡,CLAUDE_CODE_OAUTH_TOKEN 排第 5,/login 的訂閱 OAuth 憑證排第 7。照文件列的優先序,兩者同時存在時 token 排在前面。
接下來是兩個我答不出的問題。上面那 3 天警告,原文寫的是「the login you created with /login」,沒提環境變數 token。10 天那一條,changelog 的措辭是 stored claude.ai sign-in,字面上指的是存下來的登入。所以一年期 token 快到期時,有沒有警告、credential_expires_at 會不會有值,文件和 changelog 都沒說。
2.1.318 另外有一條修正,跟這個選項有關:setup-token 產的 token,在設了 forceLoginOrgUUID 的機器上,即使 token 屬於被允許的組織,啟動時也會被拒絕,這版修掉了。
想自己確認,可以看這兩個地方
可以觀察的點,我挑了這兩個,都沒跑過,貼出來只是方便你自己動手:
1 | claude auth status --text |
第一行的 exit code 是文件寫的:已登入 0,否則 1。注意前面提過,它可能碰到 token refresh,我不確定它是不是純讀取。第二行該看哪個欄位名稱,照 changelog 是 credential_expires_at,但值的格式我沒看過,你看到什麼以你看到的為準。stderr 那一行警告,如果你的定時執行把 stderr 丟掉了,這一行就沒人讀得到,這一點是我的推論,不是文件說的。
再講一次邊界:這篇是文件與 changelog 的並排,不是實測。loginExpiresAt 與 credential_expires_at 只在 changelog 看過,格式、適用範圍都沒查證;10 天與 3 天是否為同一種憑證沒查證;一年期 token 有沒有到期警告沒查證。
我的立場
要無人看守地長期跑 claude -p,我會優先走 setup-token 這條,不押在 /login 的 3 天或 10 天提醒上。理由有兩個:文件白紙黑字把它定位成給 CI 與腳本用的,一年期的壽命也比前兩個提醒窗口大得多;另外那兩個提醒的數字現在對不上,我沒辦法替你判斷該信哪一個。一年期不等於不用管,我會在行事曆上自己記下產 token 的日期,因為文件沒說它到期前會不會提醒。
你的工作如果需要 Remote Control 或 claude.ai connectors,這個選擇就不成立,token 做不到,只能回到 /login,3 天與 10 天就是你要面對的窗口。文件若補上「一年期 token 到期前有警告」,我會把行事曆提醒降成備援,不再當主力。3 天與 10 天哪天被文件說清楚是同一件事的兩個出口,我也會重寫這一段。
參考來源:Authentication(Renew an expiring login、Generate a long-lived token)、CLI reference、Errors(Login expired、Not logged in)、Headless、Changelog(2.1.317、2.1.318,皆為 changelog 標示的日期)、npm registry 發布時間(UTC)。


















