Claude Codeで環境変数が効かない
Claude Codeの環境変数が効かないときの切り分け方。env、export、.envの違いと反映の時機を、ダミー値で確かめた。
「設定したのに反映されない」。Claude Code の環境変数で一番多い悩みです。原因は、たいてい「どこに書いたか」と「いつ読まれるか」の食い違いです。この記事では、置き場所ごとの違いを公式ドキュメントで確かめ、手元で再現します。
子プロセスに秘密が漏れる話は、ここでは扱いません。「Claude Codeに秘密を渡さない」に書きました。
再現の条件
- 環境:編集部の検証環境(Linux)、Claude Code 2.1.301、GNU bash 5.2.37、Node.js v20.19.2、jq 1.7、2026-10-16。
- 一時ディレクトリを作り、
env -iで環境変数を空にしたシェルで動かしました。 - 値は、すべて
DUMMY_で始まるダミーです。
Claude Code のセッション内での反映は観察しておらず、Claude Code の挙動は公式ドキュメントによります。
まず、置き場所は3つある
| 置き場所 | 読まれる時機 | 編集したあと |
|---|---|---|
起動したシェルの export | claude の起動時 | 次に起動したときに反映 |
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 の書き方で効かない
~や$HOMEは展開されない:envの値はシェルを通さずに書き込まれるので、パスは絶対パスで書きます(出典:https://code.claude.com/docs/en/env-vars 、2026-10-16確認)。手元でも、JSON の"~/dummy-dir"はそのままの文字列でした。- 末尾のカンマやコメントはエラー:設定ファイルは厳密な JSON で、構文エラーは次の起動時に Settings Error になります(出典:https://code.claude.com/docs/en/settings 、2026-10-16確認)。保存前に
jq .で確かめると、parse errorで気づけます。 - 消したい変数は空文字で上書きする:設定ファイルでは変数を削除できないので、
"VAR": ""と書きます(出典:https://code.claude.com/docs/en/env-vars 、2026-10-16確認)。
エラーを捨てると、設定漏れに気づかない
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 の持ち越しの罠は「コーディングエージェントの選び方」に書きました。
まとめ
- シェルの export は起動時だけ読まれる。変えたら
claudeを起動し直す。 settings.jsonのenvは保存で反映される。ただし削除と、起動時だけ読む機能は再起動が必要。- 同じ変数なら、たいていは settings 側が勝つ。対になった設定キーとの優先は、組み合わせごとに確かめる。
.bashrcと.bash_profileのどちらが読まれるかは、起動のされ方で変わる。.envは自動では読まれない。~は展開されない。JSON の末尾カンマはエラー。