CLAUDE LABJP
AUTO — From August 14, auto mode becomes the default in Claude Code for Pro, Max, and Team. It only stops for actions judged irreversible, destructive, or aimed outside your environmentSAFETY — In a study with 1,053 paid testers, auto mode caught 89% of harmful actions while human review caught 13.6%HABIT — Manual review becomes habitual, Anthropic notes: users approve 97% of the permission prompts Claude Code shows themGUARD — Prompt injection screening and customizable hard deny rules have been added to keep things like data exfiltration off the tableVOICE — The head of Claude Code says he and his team have used auto mode exclusively for months and cannot imagine going back to permission promptsVERSION — The latest release is v2.1.226 from August 8, bug fixes and reliability only. Workbench retires August 17, and Sonnet 5 promo pricing runs through August 31AUTO — From August 14, auto mode becomes the default in Claude Code for Pro, Max, and Team. It only stops for actions judged irreversible, destructive, or aimed outside your environmentSAFETY — In a study with 1,053 paid testers, auto mode caught 89% of harmful actions while human review caught 13.6%HABIT — Manual review becomes habitual, Anthropic notes: users approve 97% of the permission prompts Claude Code shows themGUARD — Prompt injection screening and customizable hard deny rules have been added to keep things like data exfiltration off the tableVOICE — The head of Claude Code says he and his team have used auto mode exclusively for months and cannot imagine going back to permission promptsVERSION — The latest release is v2.1.226 from August 8, bug fixes and reliability only. Workbench retires August 17, and Sonnet 5 promo pricing runs through August 31
Articles/Claude Code
Claude Code/2026-06-18Intermediate

When a Broken settings.json Stops Claude Code From Starting — Safe Mode and How to Split Your Config

How to find which config layer is broken when a settings.json syntax error stops Claude Code from starting, recover in minutes, and structure your settings so an automated pipeline can't quietly break itself.

claude-code129settings7configuration7troubleshooting87

Premium Article

A single stray comma in a config file once stopped Claude Code from starting at all. If you hit that even once, it changes how you think about configuration. As an indie developer I run a pipeline that updates four sites automatically alongside my apps, and one morning the scheduled run had quietly stalled — I'd left a trailing comma in a hooks block I appended to .claude/settings.json. There was an error, but which file in which layer caused it wasn't obvious. That feeling — minutes draining away on triage — is the real trap with configuration.

Recent versions of Claude Code added a behavior where, when it detects a broken config, it isolates that single file and keeps starting in a degraded "safe mode." That's convenient, but if you don't understand why your usual permission rules suddenly aren't applying, it creates a different kind of confusion. Here I'll lay out what happens when config breaks, where to start triaging, and — more importantly — how to structure your settings so an automated workflow doesn't break itself in the first place.

What Claude Code does when config breaks

The first thing to internalize is that Claude Code's configuration isn't all-or-nothing. Settings are loaded from several files, and higher-priority ones override lower-priority ones. From highest to lowest:

PriorityTypeTypical path
1 (highest)Enterprise managed policymacOS: /Library/Application Support/ClaudeCode/managed-settings.json
Linux: /etc/claude-code/managed-settings.json
2Command-line arguments--model, etc.
3Project personal settings.claude/settings.local.json
4Project shared settings.claude/settings.json
5 (lowest)User settings~/.claude/settings.json

This layered structure is exactly why the behavior on breakage feels counterintuitive. Older builds could refuse to launch when any file was malformed; recent ones quarantine the broken config instead. When Claude Code finds a file it can't parse as JSON, it drops that one file from the load set and keeps starting in safe mode using the remaining valid settings.

The easy misreading here is "it started, so my settings must be applied." In reality, the permissions.deny and hooks you wrote in the quarantined file are being ignored entirely. In an automated context that produces a half-working state: a command you meant to deny falls back to ask and blocks on approval, or a hook you expected never fires and only a log remains. The "scheduled run quietly stalled" symptom I hit was exactly this pattern — a nasty gotcha when it strikes a production pipeline.

Whether you booted into safe mode shows up in the warning at startup and in /doctor, which tells you which settings file it flagged. That's the fastest place to look. I've written up how to read /doctor itself in Triaging config trouble in three minutes with /doctor.

Pinpointing which layer is broken

Recovery starts with identifying the broken file. There are at most five settings files, so mechanically validating each one as JSON surfaces the culprit immediately. This is the one-liner I run first: it parses each file with jq in priority order and bluntly flags the ones that fail.

# Validate every settings file that could be loaded, as JSON.
# Only broken files are reported as "INVALID".
for f in \
  "/Library/Application Support/ClaudeCode/managed-settings.json" \
  "/etc/claude-code/managed-settings.json" \
  "$PWD/.claude/settings.local.json" \
  "$PWD/.claude/settings.json" \
  "$HOME/.claude/settings.json"; do
  [ -f "$f" ] || continue
  if jq empty "$f" 2>/dev/null; then
    echo "OK      $f"
  else
    echo "INVALID $f"
    # Show the error with line/column of the break
    jq empty "$f"
  fi
done

Expected output looks like this — only the broken file is INVALID, and jq tells you exactly where parsing fell apart.

OK      /Users/you/project/.claude/settings.json
INVALID /Users/you/.claude/settings.json
jq: error (at /Users/you/.claude/settings.json:14): Expected another key-value pair at line 14, column 3

At that point the offending file and line are settled. If jq isn't installed, Python's standard library does the same job.

# Fallback validation when jq is unavailable
python3 - "$HOME/.claude/settings.json" << 'PY'
import json, sys
path = sys.argv[1]
try:
    with open(path) as fp:
        json.load(fp)
    print("OK", path)
except json.JSONDecodeError as e:
    print(f"INVALID {path}: {e}")
PY

The most common triage mistake is forgetting the high-priority enterprise managed policy exists. On a team-provisioned Mac, /Library/Application Support/ClaudeCode/managed-settings.json overrides your ~/.claude/settings.json, so when "I edited my user settings but nothing changed," suspect that top-level file first. Command-line arguments like --model also win over settings, so check whether a stale flag lingers in your launch script.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
If a settings.json syntax error has ever left Claude Code refusing to start, you'll understand what safe mode actually does and be able to recover in minutes
You'll get the exact commands and steps to pinpoint whether the broken config lives in the enterprise, user, project, or local layer
You'll be able to split and pre-validate your settings.json so an automated pipeline never ships a broken config in the first place
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

Claude Code2026-05-21
Claude Code Hook `command timed out`: Timeout Settings and Split-Execution Patterns That Actually Work
Fix Claude Code's `command timed out` hook failure without just bumping the timeout. Includes practical split-execution, detached background jobs, and a settings.json layout that keeps your session fast.
Claude Code2026-07-14
My MCP Timeout Was Being Ignored, and Every Call Died at Exactly 60 Seconds — Reclaiming Per-Server request_timeout_ms
A longer MCP tool call kept dying at exactly 60 seconds, ignoring the wait I had set. The cause: a per-server request_timeout_ms in .mcp.json that was never read, silently falling back to the default. Here is the correct placement after the fix, how to back the value out from a tool's response profile, and how to verify the cutoff yourself — with working code.
Claude Code2026-06-10
When git add -A Sweeps Up .bak Backups — The Quiet Trap of In-Place Fix Scripts
How .bak backups left by sed -i and homegrown --fix scripts get silently swept into production by git add -A, why it is so easy to miss, and how scoped adds and .gitignore close the gap for good.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →