Unwait

Claude Code settings: which file actually wins

· 6 min read claude code settings configuration permissions teams workflow

Five settings layers, and your personal file is the bottom one. Why your team's committed settings beat your own, which keys a repository file can never set, which ones wait for workspace trust, and the security keys where the strictest value wins no matter who set it.

You set a key, restart, and Claude Code behaves as if you had not. The reason is almost always precedence, and the stack has one feature that inverts most people's intuition.

Highest to lowest:

  1. Managed settings (managed-settings.json, MDM, or the claude.ai console)
  2. Command line (claude --settings)
  3. Project local (.claude/settings.local.json)
  4. Shared project (.claude/settings.json)
  5. User (~/.claude/settings.json)

Your personal file is the bottom of the stack. A committed team file beats ~/.claude/settings.json. That is the opposite of how most tools work, and it is the single most common reason a setting "does not apply." To get your value back in one project, put it in that project's .claude/settings.local.json, which sits above the shared file.

/status prints which files loaded and names the managed source that applies to you. Start there rather than guessing.

Lists merge, values override

When the same list key appears in several files, Claude Code combines them rather than picking one. permissions.allow from your user file, your team's file, and managed settings all apply together. This is why your organization's allow rules keep working alongside yours, unless they set allowManagedPermissionRulesOnly.

Four model keys deliberately do not merge, because position or completeness carries meaning:

Environment variables are not a level

They do not sit anywhere in that stack. Each variable and key pair is decided on its own terms. ANTHROPIC_MODEL exported in your shell wins over the model key from any file. ANTHROPIC_DEFAULT_MODEL applies only when no file sets model. Same subject, opposite behavior, and the only way to know is the reference for that specific pair.

An env block inside a settings file is just an ordinary key and follows the five levels normally.

Three things a repository file cannot do

This matters if you maintain a shared .claude/settings.json and keep wondering why teammates do not get what you committed.

Some keys never apply from a repository file at all. The settings index marks these in its Scope column as User, local, or managed, User or managed, Managed, or Global config. Most relevant in practice: permissions.defaultMode values auto and bypassPermissions do not take effect from project or local settings. Set them in user or managed settings, or pass --permission-mode for one session. If you have been reading about what the bypass mode turns off, this is the reason a checked-in file cannot switch it on for everyone.

There is one asymmetric exception worth knowing: autoContinueAtUsageLimit. A repository file cannot turn it on, but while the file sets the key and no user, --settings, or managed value does, Claude Code reads it as off. A repo can disable the wait-and-continue behavior even though it cannot enable it.

Some keys wait for workspace trust. permissions.allow, permissions.additionalDirectories, extraKnownMarketplaces, and most env values apply only after each teammate trusts the folder. Until then they still get prompts and do not get plugins from a marketplace the file declares.

Note the shape of that rule: deny and ask rules apply right away. A repository you have not trusted can restrict you immediately but cannot grant itself anything. That is the correct direction, and it is the same principle as the classifier refusing to read autoMode from project files, which we covered in the auto mode post. Treat the repository as input, not authority.

Cloud sessions read a different subset. A cloud session runs on a fresh clone, so .claude/settings.json is read because it is in the clone, while ~/.claude/settings.json and .claude/settings.local.json are not read at all. Only server-managed settings reach it; a managed-settings.json file or MDM profile on your device does not.

The security keys where strict wins over managed

Normally nothing overrides managed settings. For a handful of keys whose values restrict a session, Claude Code honors the restrictive value from a lower scope anyway:

Key Honored value
disableClaudeAiConnectors true from any scope
enableArtifact false from any scope, and disableArtifact: true
isolatePeerMachines true from any scope
remoteControlAtStartup false from project or local settings
crossSessionInbound a stricter value from project or local, on accept < hold < refuse
useAutoModeDuringPlan false from managed, --settings, user, or local
syncClaudeAiSkills false from the same four
maxEffortLevel the lowest cap from any scope

Two of those have a wrinkle: useAutoModeDuringPlan and syncClaudeAiSkills accept a false from your local file but ignore one in the shared project file. Committing false for your team does nothing; each person needs it in their own local or user file.

Why "don't ask again" keeps asking

A specific confusion worth its own section, because everyone hits it.

Choosing "Yes, and don't ask again" saves an allow rule to .claude/settings.local.json. If a project or managed file has an ask rule for the same tool, you still get prompted, because an allow rule in your local file does not outrank an ask rule from those scopes. Permission rules combine by their own order, not purely by file level.

In the VS Code extension the approval card lets you choose the destination file, including the shared project file, which changes the rule for everyone. In the CLI, Claude Code only ever writes to your local file.

Where the local file actually lives

Two details that cause "I edited it and nothing changed":

In a git repository, the local file lives at the repository root, not in the subdirectory you started from, and permission approvals apply across the whole repo. In a worktree it uses the main checkout's root. It stays beside .claude/settings.json instead when you are outside a repository, when the repo root is your home directory, on Windows, or when the root's ownership does not match your user.

Claude Code gitignores it globally, not locally. The first time it writes the file in a repository that does not already ignore it, it adds **/.claude/settings.local.json to your global git excludes file, so the pattern covers every repository on the machine. Nothing appears in the project's .gitignore. If you created the file by hand and Claude Code has not written to it yet, that has not happened, and you should add it yourself.

The five-minute triage

When a setting does not apply, in this order:

  1. /status to see which files loaded and whether a managed source applies.
  2. Check for a higher level setting the same key. Remember your user file is the bottom.
  3. Check for a variable or flag on that specific key, since those are decided per pair rather than by level.
  4. Check whether the file is allowed to set it. Project files cannot set auto or bypassPermissions as a default mode, and cannot grant allow rules before trust.
  5. Check the JSON is valid. A broken file makes Claude Code skip the file or the entry, quietly.

The organizing idea is worth holding onto, because it explains the exceptions rather than making you memorize them: settings resolve so that the party with less authority can always make a session more restricted and never less. Managed beats you on ordinary keys, you beat managed on keys that only tighten, an untrusted repository can deny but not allow, and a project file can turn off unattended continuation but not turn it on. Once that clicks, most of the table above stops needing to be a table.

Unwait does this for you

A macOS menu bar app that watches your Claude Code and Codex sessions, shows a short card while they work, and puts a strip on screen the moment one finishes. Free for two weeks, no card and no sign up.

Try for free
← All posts