Skip to content

Your Claude Code Config Isn't Applying

You added a permission rule. Nothing changed. You added it again, in a different file. Still nothing. You reinstall, and now you have two problems.

Here is the thing nobody says out loud: your edit probably worked perfectly, and is being overridden by a file you forgot you had. Claude Code reads settings from several places and merges them in a fixed order. Editing the wrong one produces the exact symptom of editing nothing at all.

The multiple files are not an accident, they are the point. Three different people want to configure the same tool and they must not overwrite each other:

You, everywhere

Preferences that follow you across every project on your machine. Your theme, your personal shortcuts.

The team, in this repo

Rules that belong to the project and should be identical for everyone who clones it. Committed to git.

You, in this repo only

Your local overrides for one project — a path that only exists on your machine, a credential you are testing. Never committed.

Your organisation

Managed policy on a company machine. Deliberately unbeatable by the three above.

Once you see it as four audiences rather than four files, the precedence order stops being arbitrary. The more specific the audience, the more it wins — except policy, which wins over everything by design.

From strongest to weakest. The first one that defines a setting is the one that takes effect.

# Source Where it lives Committed?
1 Enterprise managed policy System-wide managed settings path Managed by IT
2 Command line arguments The flags on the command you just ran
3 Project local .claude/settings.local.json No — gitignored
4 Project shared .claude/settings.json Yes
5 User ~/.claude/settings.json No

Read that table twice, because two rows account for most of the confusion.

Row 3 beats row 4. Your settings.local.json overrides the team file. If a teammate’s setup works and yours doesn’t, this is the first place to look — you probably created it weeks ago and forgot.

Row 5 loses to everything. Editing ~/.claude/settings.json to fix a project-specific problem is the single most common wasted afternoon. It is the weakest file in the chain.

Here is the same thing as a tree, which is how it actually looks on disk:

  • Directoryyour-project/
    • Directory.claude/
      • settings.json beats your user file
      • settings.local.json beats everything except policy and CLI flags
    • CLAUDE.md
    • Directorysrc/
  • Directory~/.claude/
    • settings.json the weakest file in the chain
  1. Ask the session what it loaded.

    Do not reason about it. Look at it.

    /status

    This is the ground truth. If what you see here differs from the file you edited, you have your answer already and everything below is confirmation.

  2. List every settings file that could apply.

    Run this from your project root. It finds all four candidates in one shot.

    Terminal window
    ls -la .claude/settings.json .claude/settings.local.json ~/.claude/settings.json 2>/dev/null

    Every file that prints is competing for your setting. The ones you did not know about are the interesting ones.

  3. Prove which file defines your key.

    Search all of them for the setting you are fighting with. Replace permissions with whatever you actually changed.

    Terminal window
    rg -n "permissions" .claude/settings.json .claude/settings.local.json ~/.claude/settings.json 2>/dev/null

    If the key appears in more than one file, the highest one in the precedence table wins — and it is not necessarily the one you edited.

  4. Validate the JSON before you believe the contents.

    A malformed settings file can be skipped without a loud complaint, which looks exactly like a file that is being overridden.

    Terminal window
    for f in .claude/settings.json .claude/settings.local.json ~/.claude/settings.json; do
    [ -f "$f" ] && { python3 -m json.tool "$f" > /dev/null 2>&1 \
    && echo "ok $f" || echo "INVALID $f"; }
    done
  5. Restart the session.

    Some settings are read once, when the session starts. Editing them mid-session and concluding they do not work is a self-inflicted wound. Change the file, start fresh, then judge.

Editing the user file to fix a project problem. The weakest file in the chain. If the project defines the same key, you will never see your change.

Forgetting settings.local.json exists. It is gitignored, so it is invisible in every diff and every code review. It is also the second-strongest file. That combination is why it causes so much confusion — it beats the team’s config and leaves no trace in git.

Assuming the whole file is replaced. Settings merge per key, not per file. A key you did not define is inherited from a weaker source, which means the effective config is a blend of several files and matches none of them exactly.

Trusting the file over the session. The file is what you wrote. /status is what was loaded. When they disagree, the session is right and you are debugging the wrong thing.

Editing on a managed machine. If your organisation ships a managed policy, it wins on purpose. No amount of local editing will beat it, and that is the intended behaviour — not a bug to work around.

  • /status shows the effective settings, and you compared them to your edit
  • You listed all four possible settings sources, not just the one you remembered
  • You searched every file for the key, not only the one you edited
  • .claude/settings.local.json was checked — it is gitignored and it beats the team file
  • Every settings file in play is valid JSON
  • The session was restarted after the change
  • If the machine is managed, you confirmed policy is not the thing overriding you