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晩の記録から効いたのは、賢い代替モデルではなく、生成より前に置いた短い確認。
出典
- Claude Code: Authentication
- Claude Code: Run Claude Code programmatically
- Hermes Agent: Scheduled Tasks
- Hermes Agent夜間ジョブ
28199a48b30aの2026年10月14日から16日までの実行履歴
