Claude Codeの認証切れで夜間cronが3回止まった。利用枠切れとは別に扱う

Claude Codeの認証切れで夜間cronが3回止まった。利用枠切れとは別に扱う

10月14日、15日、16日の23時。Claude Codeを呼ぶ夜間cronは、3晩続けて本文を1文字も生成しませんでした。3回ともpreflightが拾ったのは、同じ認証エラー。

Login: Expired — log in again
Not logged in. Run claude auth login to authenticate.

直前に調べた追加利用枠切れとは、停止する場所が違います。You're out of usage credits.はログイン後の利用枠で止まります。今回はClaude Codeへ処理を渡す前、ログイン状態の確認で停止。

3回分を並べると、単発ではなかった

Hermes Agentのcron履歴から、対象ジョブの直近3件を読みました。

hermes cron runs 28199a48b30a --limit 3
565db89c6ce94048b90d7d6b3b0be69d  failed     job=28199a48b30a  source=builtin  2026-10-16T23:00:55.336119+09:00
    Claude Codeの認証期限切れ(`Login: Expired / Not logged in`)をpreflightで検出したため停止しました。記事・OG・branch・PRは作成しておらず、`main`はcleanかつ`origin/main`と同期済みです。
0770f070d0514611af16e76c017bdda4  failed     job=28199a48b30a  source=builtin  2026-10-15T23:00:55.371371+09:00
    Claude Codeの事前確認で認証切れ(`Login: Expired / Not logged in`)を検出したため、生成前に停止しました。記事・OG・commit・push・PRは作成していません。ローカルbranch `content/2026-10-15-pptx-speaker-notes-metadata-check` と、未追跡ファイル `src/content/posts/ai-product-faq-source-ledger.md` は削除せず残しています。
dc8fca1f4154496bbf2f208e54425c61  failed     job=28199a48b30a  source=builtin  2026-10-14T23:00:55.319118+09:00
    Claude Code認証確認で `Login: Expired / Not logged in` のため停止しました。Claudeは起動せず、記事・OG・push・PRは未作成です。空のローカルbranch `content/2026-10-14-ai-srt-subtitle-timeline-check` のみ残しています。

表示は個人情報とホスト固有パスを省き、時刻と副作用だけ残しました。3件とも開始時刻は23時00分55秒です。Claude Codeの呼び出し前に止まったので、記事やOGはありません。

10月14日と15日の実行では、空ブランチや未追跡ファイルが残っていました。16日はbranch自体を作る前に停止しています。preflightを早く置くほど、後片付けは小さくなります。実際に残ったものの差です。

利用枠切れと認証切れを分ける

前に確認した失敗では、Claude Codeは認証済みでした。その後のモデル呼び出しでYou're out of usage credits.が返っています。今回はclaude auth status --text自体が終了コード1でした。

claude --version
2.1.289 (Claude Code)
claude auth status --text
Login: Expired — log in again
Not logged in. Run claude auth login to authenticate.

組織名とメールアドレスも表示されますが、障害の判定には不要なので公開しません。必要なのはExpired、Not logged in、終了コード1の3点です。

停止位置を図にすると、差は一段だけ。

[23:00 cron]
      |
      v
[auth status]
      |
      +-- 終了コード1 --> [生成前に停止]
      |
      +-- 終了コード0 --> [Claude Codeを1回起動]
                                  |
                                  +-- 利用枠切れ --> [生成失敗]
                                  |
                                  +-- 成功 --> [記事とOGを検証]

認証切れにモデルのfallbackを足しても、入口の手前で停止。モデルを替える前に、どの資格情報を使う運用なのかを決める必要があります。

cronの中でログインを始めない

Claude Codeの公式認証手順は、端末でclaudeを起動し、ブラウザでログインする流れです。SSHやコンテナでは、ブラウザに出たコードを端末へ戻す場合もあります。人がいない23時のcronで、この対話を始めても完了できません。

公式ドキュメントには、CIやスクリプト向けの長期OAuthトークンもあります。ただし、トークンは秘密情報です。画面へ出力したり、記事生成のプロンプトへ入れたりしてはいけません。今の夜間ジョブが対話ログインを使う設計なら、勝手に別の認証方式へ切り替えるのも避けます。

この夜間ジョブは今回、ログイン操作も認証方式の変更も行っていません。確認できたのは、3回連続で同じ入口に止まり、生成物を公開しなかったことまで。復旧操作は別の仕事です。

preflightは終了コードで止める

画面の文言だけを検索するより、コマンドの終了コードを使う方が単純です。判定は次の形で十分。

if ! claude auth status --text >/dev/null 2>&1; then
  printf '%s\n' 'Claude Code authentication is unavailable' >&2
  exit 1
fi

失敗時の期待出力は1行です。

Claude Code authentication is unavailable

この判定より前では、記事ファイル、OG、branchを作りません。認証確認に通った後も、Claude Codeの終了、記事1本、OG1枚、品質ゲート、draft: true、PR作成を別々に確かめます。ログインできたことは、原稿が完成したことではありません。

復旧は次の1回まで確認する

手動ログインでauth statusが成功しても、3回の失敗記録は消えません。見るのは、次の定時実行1回だけ。

  • preflightが終了コード0になる
  • Claude Codeの非対話実行が終了コード0になる
  • 記事1本とOG1枚だけができる
  • 記事がdraft: trueのままになる
  • 品質ゲートを通り、main向けPRが開く
  • mainへpushせず、PRをmergeしない

公式の非対話モードは、成功時に終了コード0、失敗時に0以外を返します。認証不足も失敗結果として返るため、cron側は終了コードをそのまま失敗条件にできます。

まだ復旧とは呼べない段階。10月17日8時03分の確認でも、auth statusは終了コード1でした。次の夜間ジョブが成功するまでは、3回連続失敗の状態として扱います。

実際に踏んだ差分

  • Login: Expiredなら、対話ログインまたは運用で定めた資格情報の更新が先です。
  • You're out of usage credits.なら、認証後の利用枠を確認します。再ログインだけで直るとは限りません。
  • 空ブランチや未追跡ファイルが残っても、自動で削除しません。別の作業を消す危険があるためです。
  • 失敗が続いても、同じcronを即時再実行しません。入口が変わっていない再試行は、失敗記録を増やすだけです。

認証切れは派手な障害ではありません。でも、記事生成の後で気づけば、半端なファイルや重複PRを残します。3晩の記録から効いたのは、賢い代替モデルではなく、生成より前に置いた短い確認。

出典

この記事をシェア