Pin environment variables in Claude Code's settings.json with the env key: precedence and pitfalls
How the env key in Claude Code's settings.json works: it overrides shell variables, applies to every session and subprocess, and when a saved change reaches a running session.
Contents
Putting Claude Code variables such as ANTHROPIC_MODEL or BASH_DEFAULT_TIMEOUT_MS in .bashrc or .zshrc often fails when Claude Code is launched from an IDE extension or the desktop app, because those launch paths do not run your shell initialization.
In short: variables under the env key in settings.json are read straight from the file, so they apply no matter how claude was launched, reach every session and subprocess, and override a variable of the same name set in your shell.
KEY POINT
What you will learn
- How to write the
envkey and which file reaches whom - Precedence against shell variables and between settings files
- When a saved change reaches a running session, and when it does not
Writing the env key
env is an object of variable names to string values.
{
"env": {
"API_TIMEOUT_MS": "1200000",
"BASH_DEFAULT_TIMEOUT_MS": "300000"
}
}
The variables reach not only Claude Code itself but also its subprocesses: commands run by the Bash tool, hooks, and so on. That makes env a reliable way to hand a project variable, such as a test database URL, to every command Claude runs.
The file you choose sets the scope.
| File | Applies to |
|---|---|
~/.claude/settings.json | you, in every project |
.claude/settings.json | everyone in the project, checked into source control |
.claude/settings.local.json | you, in this project only; gitignored when Claude Code writes it, add it to .gitignore yourself if you create it by hand |
| managed settings | everyone in your organization, deployed by an admin |
用語解説
Settings precedence: managed settings > command line (--settings) > project local > shared project > user. Each variable inside env resolves in that order, so a managed value overrides the same variable in user or project settings.
Precedence against the shell
When the same variable is set in your shell and in a settings env block, the settings value applies. Claude Code writes each entry into the process environment, replacing what was inherited. That makes env unsuitable for values you want to override ad hoc from the shell; for those, drop the variable from settings or use a per-launch flag such as --autocompact where one exists.
Reaching a running session
When you save settings.json, a running session applies new and changed values to its environment. Two caveats:
- A feature that reads its variables once at startup, such as OpenTelemetry monitoring, keeps its startup values until you relaunch
- Removing a variable from the file does not unset it in a running session; the removal takes effect the next time you launch
claude
Keep secrets out of the shared env block
.claude/settings.json is committed to the repository. An API key or token in its env block lands in git history. Keep personal credentials in ~/.claude/settings.json or .claude/settings.local.json, or use a mechanism such as apiKeyHelper instead of a static variable. Secret handling in general is covered in Keeping secrets away from AI coding tools.
Useful combinations
Variables whose effect is easy to see when set through env:
| Variable | Purpose | Article |
|---|---|---|
BASH_DEFAULT_TIMEOUT_MS | longer timeouts for slow tests and builds | Bash timeouts and output limits |
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE | compact earlier | Auto-compact thresholds |
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD | load CLAUDE.md from added directories | CLAUDE.md in --add-dir directories |
CLAUDE_CODE_DISABLE_AUTO_MEMORY | stop auto memory | Turning off auto memory |
The wider structure of settings.json is covered in Designing permissions in settings.json.
Summary
- Variables under
envapply to every session and subprocess regardless of how Claude Code was launched - The settings value beats a shell variable of the same name; between files, normal settings precedence applies
- Additions and changes reach a running session; startup-only features and removals wait for a relaunch
- Never put secrets in the shared
.claude/settings.json - Write values as strings
FAQ
- If a variable is set in both my shell and settings.json env, which wins?
- The settings.json value. Claude Code writes each env entry into the process environment, replacing the value inherited from the shell.
- Do changes apply to a running session when I save settings.json?
- Additions and changes do. Features that read their variables once at startup, such as OpenTelemetry, keep the old value until relaunch, and removals only take effect on the next launch.
- Do values have to be strings?
- Every official example uses strings, such as "300000". Quote numbers to be safe.
Primary sources
This article was drafted by AI from official documentation and reviewed by the site operator before publishing. Found a mistake? Let us know via the contact page.