1. TL;DR(忙しい人向け結論)
- 現象: VS CodeのClaude Code拡張機能で「
Failed to authenticate. API Error: 401 API key is invalid.」が出続けて会話できなくなる 。 - 原因: Windowsのシステム環境変数に古い/別用途の
ANTHROPIC_API_KEYを設定したため、拡張機能側がブラウザ認証トークン(OAuth)ではなく優先度の高い無効な環境変数を読み込んでしまった 。 - 解決法: Windowsの環境変数から
ANTHROPIC_API_KEYを削除し、VS Codeを完全再起動して再ログインする 。
2. はじめに(ハマった背景)
最近話題の Claude Code CLI をターミナルからエージェントとして動かそうと、Windowsのシステム環境変数に ANTHROPIC_API_KEY を登録してウキウキで開発を進めていました 。
しかしその直後、VS Codeのチャット画面(Claude Code 拡張機能)でメッセージを送ると……
Failed to authenticate. API Error: 401 API key is invalid.
Combobulating...(ローディングのままフリーズ)
何度ブラウザで再ログイン(Claude: Sign In)しても、VS Codeのウィンドウをリロードしても一向に直らない地獄のループにハマりました 。
3. 原因:認証方式の「二重取り(Auth Conflict)」
原因を探っていくと、ログの奥底に気になる警告が出ていました 。
Plaintext
Auth conflict: Both a token (claude.ai) and an API key (ANTHROPIC_API_KEY) are set
Claude Code には以下の2つの認証ルートが存在します 。
- Webトークン認証(OAuth): ブラウザから
claude.aiアカウントでログインする方式(通常使用) 。 - 環境変数 API キー認証: システムの
ANTHROPIC_API_KEYを読み込む方式 。
Windowsの「システム環境変数」は、PC内のすべてのプロセス(VS Codeを含む)に強制適用されます 。
そのため、拡張機能側が「ブラウザ認証のトークン」と「システム環境変数のAPIキー」の両方を検出してパニックを起こし、優先された環境変数側のキーが無効(または残高切れ/古かった)だったために 401 エラーで撃沈していたのが真相でした 。
4. 解決手順(Windows環境での復旧ルート)
Step 1: PowerShellで環境変数を一括削除する
VS CodeのPowerShellターミナルで、以下のコマンドを実行してユーザー/システム環境変数から該当キーを抹消します 。
PowerShell
# ユーザー環境変数から削除
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $null, "User")
# システム環境変数から削除(管理者権限推奨)
[Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", $null, "Machine")
(GUIから消す場合は Win + R ➔ sysdm.cpl ➔「環境変数」から削除可能です )
Step 2: VS Code を「完全終了」して開き直す
環境変数の変更をプロセスに読み込ませるため、VS Code を一旦すべて閉じて再起動します 。
Step 3: 再ログイン(Sign Out ➔ Sign In)
Ctrl + Shift + Pでコマンドパレットを開く 。Claude: Sign Outを実行してセッションをクリア 。- 再度
Claude: Sign Inを実行し、ブラウザでログインを許可 。
これで嘘のように元通りサクサク動くようになりました!✨
5. まとめ:得られた教訓
- Windowsのシステム環境変数は影響範囲が広すぎる: 特定のCLIツールのためだけにOS全体へ環境変数を刺すと、VS Code拡張機能など別アプリの挙動を破壊することがある 。
- Claude Code の全許可/自動化はプロジェクトローカル設定が安全: CLIや拡張機能で確認ダイアログをスキップしたい場合は、環境変数ではなくプロジェクト直下の
.claude/settings.local.jsonに許可ルールを書くのが一番安全でバッティングしません 。
JSON
{
"permissions": {
"defaultMode": "acceptEdits",
"allow": [
"Bash(*)"
]
}
}
同じエラーでハマった方の参考になれば幸いです!