Claude Code settings.json Not Loading After Edit

You edited ~/.claude/settings.json but Claude Code ignores hooks, permissions, or env on restart. Usually JSON syntax, wrong scope, or shadowed precedence.

You edited ~/.claude/settings.json or your project .claude/settings.json to add a hook, set a permission, or define an environment variable. You restart Claude Code, and nothing seems to apply: the hook never fires, the permission still prompts, the env var is empty. Claude Code reads settings from a layered file system: project local, project shared, user-global, plus enterprise. A subtle JSON syntax error, a typo in the key name, the wrong scope, or precedence shadowing can all make your edit invisible. The fix path is short once you know which scope was supposed to win and which one Claude Code is actually reading.

Common causes

Ordered by hit rate, highest first.

1. JSON syntax error invalidates the whole file

A trailing comma, an unquoted key, or a smart quote will make the entire settings file fail to parse. Claude Code falls back to defaults silently in many versions.

How to judge: Run jq . ~/.claude/settings.json. If it errors, your file is invalid.

2. You edited the wrong scope

There are at least three locations: ~/.claude/settings.json (user global), <project>/.claude/settings.json (shared, committed), and <project>/.claude/settings.local.json (local, gitignored). A user-global hook will be overridden by a project hook with the same key.

How to judge: Run ls -la ~/.claude/settings.json $PWD/.claude/settings*.json. Note which exist; precedence is local > project > user.

3. Settings key was renamed in a recent version

Claude Code occasionally renames keys (for example, permissions.allow patterns or hook schema). Your old key sits in the file unused.

How to judge: Compare your keys against the current docs version. Unknown keys are silently ignored.

4. Environment variables defined under the wrong block

Setting env under the wrong scope or with wrong types (string-only) can make Claude Code drop them. Numeric or boolean values must still be expressed as strings in some versions.

How to judge: After restart, run claude --debug and look for env loading lines. Missing means rejected.

5. File permissions block Claude Code from reading the file

If you edited as root or via a script, the file may now be 600 root-owned. The user-launched Claude Code process cannot read it.

How to judge: stat -f '%Su %Lp' ~/.claude/settings.json (macOS) or stat -c '%U %a' ~/.claude/settings.json (Linux). If owner is not you or perms are restrictive, fix it.

6. Claude Code is still running the old session

Many settings only load at session start. An open session keeps the values it loaded.

How to judge: Did you actually quit Claude Code (/exit or close the terminal) before re-launching? If not, you are in the old session.

Before you start

  • Back up the settings.json file before editing.
  • Decide which scope you really want (user-global vs project-shared vs project-local).
  • Know whether your change should apply only to you, your whole team, or just this project session.
  • Make sure jq is installed; you will use it for validation.

Information to collect

  • Claude Code version: claude --version.
  • OS and which user is running Claude Code: whoami.
  • Output of ls -la ~/.claude/ and ls -la .claude/ from your project.
  • The full contents of any settings.json files involved.
  • Output of jq . ~/.claude/settings.json (errors if any).
  • A debug log: claude --debug 2>&1 | head -200.

Step-by-step fix

Step 1: Validate JSON syntax

jq . ~/.claude/settings.json
jq . .claude/settings.json 2>/dev/null
jq . .claude/settings.local.json 2>/dev/null

A parse error halts further investigation; fix that first. Watch out for trailing commas after the last item in an object or array.

Step 2: Check which scope is winning

Claude Code merges layers with this precedence (highest first):

  • Enterprise managed (if present)
  • .claude/settings.local.json (project, local)
  • .claude/settings.json (project, shared)
  • ~/.claude/settings.json (user)

If two files define the same key, only the higher-precedence wins. Move your edit to the right layer, or remove the lower one.

Step 3: Use debug mode to confirm load

claude --debug 2>&1 | grep -i settings

You should see lines mentioning settings paths and the keys loaded. Missing entries mean the file was skipped.

Step 4: Verify file ownership and perms

ls -la ~/.claude/settings.json
chmod 600 ~/.claude/settings.json
chown $USER ~/.claude/settings.json

The file must be readable by the user running Claude Code.

Step 5: Diff against a known-good template

If you are unsure of current schema, copy the example from the docs into a scratch file, validate it with jq, then port your customizations one key at a time, restarting after each.

Step 6: Fully restart Claude Code

Type /exit, close the terminal pane, and relaunch in a new shell. Some shells cache env that the CLI inherits.

Step 7: For env, double-check the type

{
  "env": {
    "MY_API_BASE": "https://api.example.com",
    "DEBUG": "true"
  }
}

Use strings even for booleans and numbers, then convert in your script.

Verify

  • The hook now fires on the matching tool call.
  • The permission rule actually allows or denies as configured.
  • printenv MY_VAR (inside a Bash tool call) returns the expected value.
  • Restarting Claude Code does not reset behavior — the load is persistent.

Long-term prevention

  • Always validate settings.json with jq after editing. Add this to a pre-commit hook for the project.
  • Keep a settings.example.json in your dotfiles repo with comments explaining each block.
  • Avoid mixing user-global and project-local entries for the same hook; pick one home.
  • Use .claude/settings.local.json for personal overrides that should not be committed.
  • Track schema changes in Claude Code release notes; rename keys promptly.

Common pitfalls

  • Adding a comment line (// or #) into JSON. JSON does not support comments; some loaders are forgiving, Claude Code is not.
  • Trailing commas after the last array element. Strict JSON rejects them.
  • Editing the file with an editor that injects smart quotes or BOM.
  • Putting hook definitions in settings.local.json and committing it by accident.
  • Forgetting that opening a new session is required for changes to take effect.

FAQ

  • Which settings file wins if I have both? Enterprise > project local > project shared > user global. The most specific layer wins per key.
  • Can I have comments in settings.json? No, strict JSON only. Use a separate notes file or keys named _comment if you must annotate.
  • Why is my env var still empty? It may be defined under the wrong scope, or the value is non-string. Quote everything.
  • Do hook changes need a restart? Yes — hooks load at session start.
  • Where is the schema documented? Anthropic publishes a settings reference; check the version that matches your claude --version.
  • Can I validate without restarting Claude Code? Yes, run jq . settings.json. It will not catch unknown keys, but it catches syntax errors.

Tags: #Claude Code #settings #Troubleshooting #CLI