Grokの403でcronが止まった。API呼び出し0回の50件のうち、19件は「完了」と記録されていた

Grokの403でcronが止まった。API呼び出し0回の50件のうち、19件は「完了」と記録されていた

9月30日から10月2日までの3日間、Hermes Agentのcronセッションは19件が cron_complete で終わっていました。終了理由だけを見ると、全部うまくいった日です。

ところがその19件は、APIを1回も呼んでいませんでした。入力トークンも0です。Grokの利用枠が尽きていて、403で門前払いされていました。

私はAIエージェントに毎日の調べ物や下書きを任せています。仕事の土台はcronです。止まったのに「完了」と書かれるなら、朝の確認は何を見ればいいのでしょうか。数え直した記録を残します。

最初のgrepは55件。エラーは45件でした

cronの出力は、ジョブごとのフォルダに1回1ファイルで残ります。まず、利用枠切れのときに出る語を探しました。

cd ~/.hermes/cron/output
grep -rliE 'spending.?limit' . | wc -l
55

55件。ここから数えようとして、すぐ手が止まりました。ファイルを開くと、エラーそのものではなく、プロンプトや要約が「spending-limitが出たら別モデルに固定する」という手順を引用しているだけのものが混じっています。

エラー本文は、RuntimeError: HTTP 403: で始まる1行です。この行をそのまま固定文字列で探し直しました。

grep -rlF 'RuntimeError: HTTP 403: {"code":"personal-team-blocked:spending-limit"' . | wc -l
45

差の10件は、Pinterestの3日ごとのレビュー(7件)、夜稿(2件)、もう1つのジョブ(1件)が、その語を文中で触れただけのものでした。エラー45件が出たジョブは18本です。

「語が出るファイル」と「エラーを起こしたファイル」は別でした。ここを混ぜたまま日別表を作っていたら、10月4日から22日まで3日おきに失敗が続いたことになるところでした。

出力ファイルには残らない失敗がある

45件で数え終わりにしなかったのは、cronのセッション側にも記録があるからです。Hermesは ~/.hermes/state.db に、セッションごとの終了理由、API呼び出し数、入力トークン数を持っています。公式に形が保証された出力ではないので、読み取り専用で開きます。

条件は「cronのセッションで、API呼び出しが0回、入力トークンも0」にしました。

import sqlite3
from datetime import datetime
from pathlib import Path

db = Path.home() / ".hermes" / "state.db"
con = sqlite3.connect(f"file:{db}?mode=ro", uri=True)
start = datetime(2026, 9, 20).timestamp()
sql = """
select date(started_at, 'unixepoch', 'localtime') as day,
       model, end_reason, count(*)
from sessions
where source = 'cron'
  and started_at >= ?
  and api_call_count = 0
  and input_tokens = 0
group by day, model, end_reason
order by day
"""
total = 0
for day, model, reason, n in con.execute(sql, (start,)):
    total += n
    print(day, model, reason, n)
print("total", total)

このスクリプトを zero_calls.py に保存して python3 zero_calls.py で実行した出力です。

2026-09-21 grok-4.6 cron_incomplete_no_output 5
2026-09-22 grok-4.6 cron_incomplete_no_output 12
2026-09-23 grok-4.6 cron_incomplete_no_output 4
2026-09-24 grok-4.6 cron_incomplete_no_output 3
2026-09-25 grok-4.6 cron_incomplete_no_output 6
2026-09-28 grok-4.7 cron_incomplete_no_output 1
2026-09-30 grok-4.7 cron_complete 8
2026-10-01 grok-4.7 cron_complete 9
2026-10-02 grok-4.7 cron_complete 2
2026-10-05 claude-sonnet-5-5 cron_complete 1
total 51

51件です。波が2つあります。

期間件数終了理由
9月21日から28日31cron_incomplete_no_output
9月30日から10月2日19cron_complete

前半は「出力なしで未完」と記録されます。ここは見れば異常だと分かります。後半は同じ0回なのに、終了理由が「完了」です。10月1日分の出力ファイルを開くと、## Error の下に403が書かれています。完了の印が付いたまま、中身は失敗でした。

9月26日から29日の4日間は、28日の1件を除いてGrokが動いていて、30日にまた止まっています。切れて、戻って、また切れています。利用枠の側で何が起きたのかは、私の手元の記録からは分かりません。

数が合わない6件を、そのままにしておく

セッションの51件と、エラーファイルの45件は一致しません。差の6件の中身は次のとおりです。

  • Grokのセッションで、エラーファイルが残っていないもの: 5件(9月21日に3件、9月28日と30日に1件ずつ)
  • 10月5日のClaudeセッション: 1件

前者の5件は、API呼び出しが0回という点では同じです。ただ、403だったと言える文字列がありません。同じ時期、同じモデルなので利用枠切れだったと考えるのが自然です。私はそう読みますが、確認できたのは45件だけです。後者は原因を調べていないので、ここでは扱いません。

10月3日以降と、残っている不安

10月3日から24日の22日間で、cronのセッションは367件です。主なモデル別では、gpt-6-solが179件、claude-sonnet-5-5が150件、grok-4.7は13件でした。13件は、API呼び出しが1回以上ありました。API呼び出しが0回のセッションは、先ほどのClaudeの1件だけです。

ジョブごとに別プロバイダへ固定していった結果、API呼び出し0回の日はほぼ消えました。

不安は残っています。hermes config get cron.model は今も grok-4.7、プロバイダは xai-oauth を返します。有効なジョブ32本のうち、個別に固定していないのは9本、Grokに固定したままなのが4本です。この13本は、Grokの利用枠がまた切れれば同じ失敗を繰り返します。

そのとき「完了」を信じて朝の確認を省くと、止まったことに気づくのが遅れます。今回の2つ目の波は、終了理由だけを見ていては気づけない形でした。

朝に見る場所を変える

結局、終了理由の列は信用の根拠に使えませんでした。見るのは次の2つです。

  • API呼び出しが0回で、入力トークンも0のcronセッションが、前日に1件でもあるか
  • あれば、そのジョブの出力ファイルの ## Error に何が書かれているか

どちらも、上のスクリプトとgrepを手で実行して確かめた方法です。毎日自動で回す仕組みにまでは、まだしていません。

出典

この記事をシェア