claude-code-actionでCredit balance is too lowが出る原因と回避策
残高がありclaude -pは通るのに、claude-code-actionだけ「Credit balance is too low」で落ちる報告です。環境変数での切り分けと、報告者が試した回避策を載せます。
claude-code-actionでCredit balance is too lowが出る原因と回避策
コンソールには残高があり、同じジョブの中で claude -p を直接動かすと課金されて通る。それなのに anthropics/claude-code-action@v1 だけが約0.5秒で Credit balance is too low を返して終わる。2026年10月13日に立ったissueには、最初の報告とコメントを合わせて5人分の報告が並んでいます。
結論から書くと、残高やキーを疑う前に、アクションが子プロセスに渡す環境変数 CLAUDE_CODE_ENTRYPOINT と CLAUDE_CODE_ACTION を疑う段階にあります。原因についてAnthropic側の説明はissue #1901に出ておらず、以下は報告者の検証結果です。確定した原因ではありません。
症状の見分け方
次の3点がそろうと、このissueと同じ型です。
- ログに
Credit balance is too lowが出る。is_error: true、duration_msは400〜900ms程度、total_cost_usdは0、modelUsageは空 curlで/v1/messagesを叩くと200が返る- 同じジョブ・同じシークレットで
claude -pを直接実行すると正常に課金される
アクションは実行ログにClaudeの出力を出さないため、エラー文はアクションの出力 execution_file を jq で開いて初めて読めます。ログが「SDK execution error」としか出ないときの読み出し方は「SDK execution error」の記事にまとめています。
落とし穴
残高が足りていても同じ文言が返る
Credit balance is too low は残高不足以外でも返ることが、別のissue(#1224)で報告されています。挙げられている原因は3つで、実際の残高枯渇、要求したモデルがアカウントの利用ティアに足りないこと、キーは認証されるのに課金先のアカウントに紐づいていない「孤立キー」です。文言から原因を決め打ちできません。
失敗する実行でも、最初の init メッセージは正常に見えます。apiKeySource は ANTHROPIC_API_KEY、permissionMode は acceptEdits、コメント用のMCPサーバー github_comment は connected で、認証の読み込み自体には失敗していません。拒否はその後の最初のAPIリクエストで起きており、1ターン目で終わります。そのため、ログの冒頭だけを見て「認証は通っている」と判断すると、原因の切り分けが遠回りになります。
最初に切り分ける3つの比較
最初に確かめるのは、アクション経由かどうかだけが違うのか、という点です。ワークフローの最後に if: always() の診断ステップを足し、同じシークレットで次の3つを比べます。
# 1. APIに直接送る(キー・残高・ワークスペースの確認)
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"<使っているモデルID>","max_tokens":1,
"messages":[{"role":"user","content":"hi"}]}'
# 2. アクションがインストールしたCLIを直接実行
~/.local/bin/claude -p "say ok"<使っているモデルID> はワークフローの --model に渡している値に合わせます。issueの報告者は、(1)が200、(2)も正常という結果を得ています。この2つが通るなら、キーと残高の問題ではありません。
3つ目として、アクションが作るプロンプトファイルをそのままCLIに渡す方法も報告されています。
claude -p --permission-mode acceptEdits --max-turns 1 \
< "$RUNNER_TEMP/claude-prompts/claude-prompt.txt"最初の報告者の環境では、アクションが作った16KBのプロンプトを渡してもAPI呼び出しは受理され、課金されました。プロンプトの中身が原因ではないことになります。
環境変数の二分探索で見えたこと
報告者の1人は、アクションが claude の実行ファイルを起動するときの環境(path_to_claude_code_executable 経由で export -p した内容)を再現し、変数を1つずつ外して結果を比べています。
| 外した変数 | 結果 |
|---|---|
CLAUDE_CODE_ENTRYPOINT だけ | 結果失敗 |
CLAUDE_CODE_ACTION だけ | 結果失敗 |
| 両方 | 結果成功 |
| 2つ以外を全部外す | 結果失敗 |
どちらか一方が残っていれば拒否されるため、CLAUDE_CODE_ENTRYPOINT だけを外して直らなかった人が出るのも、この表で説明がつきます。作業ディレクトリを変えても、アクションが渡す空の ANTHROPIC_* 変数を消しても、結果は変わりませんでした。
別の報告者は、CLAUDE_CODE_ENTRYPOINT=claude-code-github-action だけを設定した claude -p で、同じキーのまま400が再現したと書いています。GITHUB_ACTIONS=true と CI=true だけでは再現しません。ログ用のプロキシで2つのリクエストを比べると、違いはセッションIDのほかに2点でした。
user-agentがclaude-cli/2.1.296 (external, cli)ではなく(external, claude-code-github-action)- 最初の
systemブロックにある課金用ヘッダーのcc_entrypointがclaude-code-github-action
この報告者は、キー・残高・モデル・プロンプト・クライアント版ではなく、アクションの印が付いたリクエストの課金側の扱いで拒否されているように見える、と推測しています。推測であり、APIの挙動としてAnthropicが説明した内容ではありません。
原因が1つに決まらない理由
同じ症状に見える報告でも、条件は食い違っています。
- 認証方式: APIキー(組織のサービスアカウント含む)でも、Workload Identity Federationでも起きた
- ネットワーク: 内部ゲートウェイ経由(
ANTHROPIC_BASE_URL)でも、GitHubホストのubuntu-latestでも起きた - ランナー: セルフホストLinuxでも
ubuntu-latestでも起きた
認証方式を問わず出ていることは、キーの種類より起動経路に原因があるという見立てと整合します。ただし、見立ての域を出ません。
バージョンを固定しても直らなかった
最初の報告では、v1.0.248(同梱のClaude Codeは2.1.296)で失敗し、v1.0.247(2.1.295)以前は動いたという表が出ています。回避策としてv1.0.247のコミットSHAへ固定する案も添えられました。
しかしその後、効かなかったという報告が3件続きます。
- v1.0.247でも同じく失敗した(Claude Code 2.1.295)
- 組織のサービスアカウントのキーで、v1.0.247に固定しても
Credit balance is too low - v1.0.247の
parse-sdk-options.tsも同じCLAUDE_CODE_ENTRYPOINTを設定している、という指摘
版の固定が効いた最初の報告は、時期の違いで偶然通っていた可能性が指摘されています。固定するなら、固定後に実際に通ることを必ず確かめます。
報告者が検証した回避策
実際のPRレビュー実行で is_error: false となり、レビューが投稿されたと報告されているのは、2つの変数を外すラッパーです。次はその報告の形をそのまま載せたもので、公式の手順ではありません。
- name: Install Claude Code without the action markers
run: |
curl -fsSL https://claude.ai/install.sh | bash
printf '#!/bin/sh\nunset CLAUDE_CODE_ENTRYPOINT CLAUDE_CODE_ACTION\nexec "%s" "$@"\n' \
"$HOME/.local/bin/claude" > "$RUNNER_TEMP/claude"
chmod +x "$RUNNER_TEMP/claude"
- uses: anthropics/claude-code-action@v1
with:
path_to_claude_code_executable: ${{ runner.temp }}/claude
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}アクションの入力 settings の env で CLAUDE_CODE_ENTRYPOINT を cli に上書きする方法も試され、効きませんでした。ラッパーの仕組みは、実行ファイルを呼ぶ直前にシェルで変数を消す、というものです。
使う前に押さえておく点が3つあります。
- 印を消すと、アクション経由の利用がAPI側で通常のCLI利用と同じ扱いになります。意図した状態かどうかは、利用規約と社内ルールに照らして自分で判断する必要があります
path_to_claude_code_executableは、アクションが標準で入れるCLIの代わりに自前のものを使う入力です。CLIの更新は自分で追うことになります- インストールスクリプトをワークフロー内で都度取得するので、取得元の変更に影響されます。固定したい場合は版を指定したインストール方法に置き換えます
アクションの入力と claude_args の渡し方の全体像はGitHub Actionsのパラメータとclaude_argsにあります。
残高そのものを疑う場合
上の切り分けで curl や claude -p も失敗するなら、アクションとは無関係な本物の課金問題です。
別のissue(#1053)では、anthropic_api_key に残高のあるキーを設定しても同じエラーになるという報告があり、報告者はClaude Codeのサブスクリプションかアクセストークンが必要なのだと推測しています。ただし、これは報告者の推測として書かれたものです。公式のGitHub Actionsドキュメントは、APIキー(anthropic_api_key)とOAuthトークン(claude_code_oauth_token)の2種類を、どちらもサポートする認証として載せています。
OAuthトークンで認証した場合、実行はAPI課金ではなくClaudeサブスクリプションの利用枠で扱われます。APIキーで原因が分からないとき、サブスクリプションを持っているなら claude setup-token で作ったトークンに切り替えて挙動を比べるのも、切り分けの1手です。Workload Identity Federationの構成はWIFとGitHub Actionsの連携手順で扱っています。
ワークスペースを指定したキーの場合
最初の報告者は、組織のサービスアカウントのキー(ワークスペースに紐づかないタイプ)を使い、ステップに ANTHROPIC_CUSTOM_HEADERS: "anthropic-workspace-id: <ワークスペースID>" を足していました。診断ステップの curl と claude -p にも同じヘッダーを付けて通っているため、ヘッダー自体は原因ではありません。
ただし、この構成では課金先がワークスペースで決まります。診断の3経路を比べるときは、本番のステップと診断のステップで、次の3点を一致させます。
- 同じシークレット(別名のシークレットに同じ値を入れ直していないか)
- 同じ
ANTHROPIC_CUSTOM_HEADERS - 同じモデルID(ティアが足りないモデルだけ弾かれる場合があるため。#1224の原因2)
報告者はこのほか、通常のコンソールキーに戻す、キーを何度も作り直す、新しい組織のサービスアカウントキーを作る、という手も試しましたが、どれも結果は変わりませんでした。キーの再発行を繰り返す前に、起動経路の比較を先にしたほうが早く絞れます。
公式ドキュメントとの食い違い
公式のGitHub Actionsドキュメントのトラブルシューティング節には、認証エラーとして「ローカルで claude を使ってキーを検証する」と書かれています。この手順で claude が通ると、キーは問題なしと判断してしまいますが、今回の症状ではそこで通ります。
つまり、ローカルのCLIで通ることは、アクション経由で通ることの保証にならない、というのがこのissueの要点です。ドキュメントの節には CLAUDE_CODE_ENTRYPOINT などの環境変数や、このエラー文言への言及はありません。
まとめ
CLIでは通るのにアクションでだけ Credit balance is too low になるなら、curl・claude -p・アクションの3経路を同じジョブで比べ、アクション経由だけが落ちるかを最初に確かめます。落ちるなら、CLAUDE_CODE_ENTRYPOINT と CLAUDE_CODE_ACTION を外したラッパーが、issueで通ったと報告されている回避策です。
版の固定は効いた報告と効かなかった報告が割れています。状況の変化は#1901のコメント欄で追えます。