ターミナルで /login をやり直すと、画面には「Login successful」と出ました。それなのに、スクリプトの中から呼んだ claude -p だけが、同じようにログインを拒むのです。
こういう場面で手が止まるのは、ログインそのものが壊れているように見えるからだと思います。再ログインを二度、三度と繰り返し、ブラウザのタブだけが増えていく——そんな遠回りを、できれば皆さまには避けていただきたいのです。
最初にお伝えしたいのは、多くの場合、壊れているのはログインではなく「どの資格情報が選ばれているか」の側だということです。公式の認証ドキュメントには、Claude Code が資格情報を選ぶ順番がはっきり書かれています。私はその順番を、手元で確かめる手順に置き換えて書き残しております。
まず /status で、実際に使われている方法を見る
再ログインの前に、対話画面で /status を開きます。ここで見るのは、ログイン方法の行です。
ドキュメントによると、ログインと API キーが両方設定されているときは、使われていないほうに印が付きます。プロファイルが選ばれているときは、ログイン方法の行の代わりに Profile の行が出ます。保存済みの claude.ai ログインが有効な資格情報であるときに限り、期限切れの場合は Login の行に「Expired — log in again」と出ます(v2.1.210 以降)。
私は /status を、「いま誰の名前で動いているか」を教えてくれる画面だと受け止めています。ここを見ずに /login へ進むのは、鍵穴を確かめずに鍵を打ち直すのに似ています。
優先順位の表を、手元のメモに写しておく
Claude Code は、複数の資格情報があるとき、次の順で一つを選びます。上にあるものが勝ちます。
| 順位 | 資格情報 | 気をつけたい点 |
|---|---|---|
| 1 | Bedrock / Vertex / Foundry の設定変数 | CLAUDE_CODE_USE_BEDROCK などが残っていると、ほかは見られません |
| 2 | ANTHROPIC_AUTH_TOKEN | ゲートウェイ向けの Bearer トークンです |
| 3 | ANTHROPIC_API_KEY | -p では、あれば必ず使われます |
| 4 | apiKeyHelper の出力 | スクリプトが失敗すると、数回の試行のあとで要求が失敗します |
| 5 | CLAUDE_CODE_OAUTH_TOKEN | claude setup-token で作る長期トークンです |
| 6 | Anthropic プロファイル | ANTHROPIC_PROFILE で名前を指すと /login より上になります |
| 7 | /login のサブスクリプション認証 | Pro / Max / Team / Enterprise の既定です |
/login は、一番下の七番目です。ここだけを直しても、上の六つのどれかが居座っていれば、結果は変わりません。
-p だけ失敗するいちばんの理由は、環境変数の API キーです
対話モードでは、ANTHROPIC_API_KEY が見つかると、使うかどうかを一度だけ尋ねられ、その答えが記憶されます。ところが -p(非対話モード)では、キーがあれば必ず使われます。尋ねてはくれません。
たとえば、サブスクリプションで契約していて、シェルの設定ファイルに古い API キーが残っていたとします。対話では「使わない」と答えた記憶が効いて普通に動き、-p だけが、無効になった組織のキーで認証に向かう——ドキュメントにも「無効または期限切れの組織のキーだと認証に失敗する」と書かれています。
確かめ方は、キーの中身を表示せず、設定の有無だけを見ることです。
# 何を解決するか: 資格情報の優先順位に関わる変数が、いまのシェルにあるかを一覧する
# (値は表示しません。bash 専用の書き方です)
for v in CLAUDE_CODE_USE_BEDROCK CLAUDE_CODE_USE_VERTEX CLAUDE_CODE_USE_FOUNDRY \
ANTHROPIC_AUTH_TOKEN ANTHROPIC_API_KEY CLAUDE_CODE_OAUTH_TOKEN \
ANTHROPIC_PROFILE CLAUDE_CONFIG_DIR; do
if [ -n "${!v}" ]; then echo "$v: set"; else echo "$v: -"; fi
doneANTHROPIC_API_KEY: set が見つかり、心当たりがなければ、unset ANTHROPIC_API_KEY を試します。サブスクリプションに戻ったかどうかは、もう一度 /status で確認できます。
私が値を出さない形にしているのは、画面共有やログの貼り付けで、キーがそのまま残ってしまうのを避けたいからです。一度出た値は、あとから引っ込められないからです。
無人で動かすなら、ブラウザのログインを持ち込まない
定期実行やスクリプトでは、ブラウザで承認するログインが使えません。そのための仕組みが、長期トークンです。
# 何を解決するか: 対話ログインできない環境へ、サブスクリプションの認証を渡す
claude setup-token
# 承認するとトークンが画面に出ます。保存はされないので、控えてから設定します
export CLAUDE_CODE_OAUTH_TOKEN=your-tokenこのトークンの性質は、押さえておく価値があります。有効期間は一年で、Pro・Max・Team・Enterprise のプランが必要です。モデルへの要求だけができ、Remote Control のセッションや claude.ai のコネクタは使えません。そして --bare を付けた実行はこの変数を読まないため、その場合は API キーか apiKeyHelper を使います。
「ログインできているのに、コネクタだけ出てこない」と感じたら、トークンの性質のほうを疑うのが近道です。
動く場所によって、資格情報の置き場所が違います
同じ claude でも、実行する場所で読むものが変わります。
macOS では、資格情報は Keychain に入ります。SSH セッションなどで Keychain が書き込みを拒むと、~/.claude/.credentials.json に保存されます。CLAUDE_CONFIG_DIR を設定している場合は、そのディレクトリの下のファイルが使われ、Keychain の項目もディレクトリごとに別になります。
つまり、手元の端末と、別の設定ディレクトリで動くスクリプトとは、別々のログインを見ているかもしれないのです。
もう一つ、クラウドセッションと Claude Desktop は、apiKeyHelper や ANTHROPIC_API_KEY を読みません。OAuth を使います。クラウド側の環境にキーを置いても、サブスクリプションの資格情報は上書きされません。クラウドで claude -p を呼んでログインの表示が噛み合わないときは、リリースの変更履歴に修正が入っていないかも見てみてください。私が見かけた要約では、直近の版でそうした誤表示が直された、という記述がありました。細部は必ずご自身で変更履歴の本文を確かめていただければ幸いです。
期限切れだけは、再ログインが正解です
優先順位を全部確かめても、/status に「Expired — log in again」が出ているなら、再ログインが正解です。
保存済みのログインは、期限の三日前から起動時に警告を出します。警告が出ても要求は止まりませんが、期限が来て更新できなくなると、要求のたびに「Login expired · Please run /login」で失敗します。無人で長く動いているセッションは、そこで進まなくなり、自力では戻れません。
私が決めている、確かめる順番
ここまでを一本にすると、次の順番になります。
/statusで、実際に使われている方法を確認します- 上のスクリプトで、優先順位に関わる変数を一覧します
-pや無人実行では、API キーと長期トークンのどちらを使うかを決めます- 動く場所(端末・SSH・クラウド)の資格情報の置き場所を思い出します
- 期限切れのときだけ、
/loginをやり直します
ログインを直す前に、どの資格情報が勝っているかを一度だけ言葉にします。 私はこの線引きを守るようにしています。それだけで、再ログインの回数は、ずいぶん減るのだと思います。
まずは今日の端末で /status を開き、変数の一覧を一度だけ出してみていただけますか。そこで見えた名前を、メモに一行残しておくと、次に同じ表示を見たとき、手が止まらずに済みます。