Pin environment variables in Claude Code's settings.json with the env key: precedence and pitfalls

Claude Code Published:

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.

Verified on Sep 10, 2026 These tools change quickly. Please also check the latest official documentation.
Contents
  1. Writing the env key
  2. Precedence against the shell
  3. Reaching a running session
  4. Useful combinations
  5. Summary

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 env key 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.

FileApplies to
~/.claude/settings.jsonyou, in every project
.claude/settings.jsoneveryone in the project, checked into source control
.claude/settings.local.jsonyou, in this project only; gitignored when Claude Code writes it, add it to .gitignore yourself if you create it by hand
managed settingseveryone 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:

VariablePurposeArticle
BASH_DEFAULT_TIMEOUT_MSlonger timeouts for slow tests and buildsBash timeouts and output limits
CLAUDE_AUTOCOMPACT_PCT_OVERRIDEcompact earlierAuto-compact thresholds
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MDload CLAUDE.md from added directoriesCLAUDE.md in --add-dir directories
CLAUDE_CODE_DISABLE_AUTO_MEMORYstop auto memoryTurning off auto memory

The wider structure of settings.json is covered in Designing permissions in settings.json.

Summary

  • Variables under env apply 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.