創刊準備号 · 2026年秋English · RSS
AgentKoji

Claude Codeで環境変数が効かない

Claude Codeの環境変数が効かないときの切り分け方。env、export、.envの違いと反映の時機を、ダミー値で確かめた。

「設定したのに反映されない」。Claude Code の環境変数で一番多い悩みです。原因は、たいてい「どこに書いたか」と「いつ読まれるか」の食い違いです。この記事では、置き場所ごとの違いを公式ドキュメントで確かめ、手元で再現します。

子プロセスに秘密が漏れる話は、ここでは扱いません。「Claude Codeに秘密を渡さない」に書きました。

再現の条件

Claude Code のセッション内での反映は観察しておらず、Claude Code の挙動は公式ドキュメントによります。

まず、置き場所は3つある

置き場所読まれる時機編集したあと
起動したシェルの exportclaude の起動時次に起動したときに反映
settings.json の env起動時、保存したとき動いているセッションにも反映。ただし削除は次の起動から
プロジェクトの .env自動で読むという記述は見当たらない—

出典:https://code.claude.com/docs/en/env-vars 、2026-10-16確認。OpenTelemetry のように起動時に一度だけ読む機能は、起動し直すまで元の値のままです(同出典)。

同じ変数が両方にあるとき

シェルと settings.json の env の両方に同じ変数があると、たいていは settings 側が勝ちます(同出典)。ただし ANTHROPIC_MODEL と model キーのように、環境変数と設定キーが対になっているものは、組み合わせごとに優先が決まっています(出典:https://code.claude.com/docs/en/settings 、2026-10-16確認)。プロジェクト側の env の多くは、フォルダを「信頼」するまで適用されません(同出典)。

Bash で export しても、次のコマンドには残らない

Claude Code の Bash ツールでは、あるコマンドでした export は、次のコマンドに残りません(出典:https://code.claude.com/docs/en/tools-reference 、2026-10-16確認)。別々のシェルを起動して確かめました。

$ bash -c 'export DUMMY_TIMEOUT_MS=1200000; echo "1回目: ${DUMMY_TIMEOUT_MS:-(未設定)}"'
1回目: 1200000
$ bash -c 'echo "2回目: ${DUMMY_TIMEOUT_MS:-(未設定)}"'
2回目: (未設定)

セッションの間ずっと残したいなら、起動の前に CLAUDE_ENV_FILE にシェルスクリプトを指定するか、SessionStart の hook で中身を書き出します(同出典)。hook の書き方は「Claude Code hooks実践」に書きました。

~/.bashrc に書いた export はどこで効くか

公式の案内は「~/.bashrc などに export を書く」です(出典:https://code.claude.com/docs/en/env-vars 、2026-10-16確認)。claude を起動するシェルに読ませるためです。そのシェルがどのファイルを読むかが落とし穴なので、空の HOME に .bash_profile と .bashrc を置いて試しました。

bash -c  profile=なし                     bashrc=なし
bash -lc profile=sk-dummy-0000-NOT-REAL   bashrc=なし
bash -ic profile=なし                     bashrc=sk-dummy-0000-NOT-REAL

ログインシェルは .bash_profile、対話シェルは .bashrc を読み、bash -c はどちらも読みません。PATH に足したディレクトリも、書いたファイルが読まれない起動の仕方では入りません。起動の仕方に左右されたくない値は、「claude をどう起動しても効く」と公式が書いている settings.json の env に置きます(同出典)。

.env は自動では読まれない

プロジェクトの .env は、Claude Code にとっては、ただのファイルとして扱うのが安全です。公式の環境変数のドキュメントにも、.env を自動で読むという記述はありません(2026-10-16確認)。アプリが .env を使うなら、アプリ側で読み込みます。Node なら --env-file です。

$ node -e 'console.log(process.env.DUMMY_API_KEY ?? "undefined")'
undefined
$ node --env-file=.env -e 'console.log(process.env.DUMMY_API_KEY)'
sk-dummy-0000-NOT-REAL

settings.json の書き方で効かない

エラーを捨てると、設定漏れに気づかない

source .envrc 2>/dev/null は、ファイルが無くても黙って先に進み、変数は空のままです。編集部では、一部のコマンドだけが認証エラーで落ちて、原因の特定が遅れました。

$ bash -c 'source ./.envrc 2>/dev/null; echo "exit=$? DUMMY_TOKEN=${DUMMY_TOKEN:-(空)}"'
exit=1 DUMMY_TOKEN=(空)

エラーを捨てず、&& でつなぎます。

direnvで自動で読み込む

外部ツールの direnv は、プロンプトを出すときのフックで環境を切り替えるので、Claude Code の Bash ツールではそのままでは動きません。公式には、作業ディレクトリが変わったときに発火する CwdChanged の hook があり、direnv のような用途に使えて、CLAUDE_ENV_FILE に書き込めると書かれています(出典:https://code.claude.com/docs/en/hooks 、2026-10-16確認)。cwd の持ち越しの罠は「コーディングエージェントの選び方」に書きました。

まとめ