You upgrade to Claude Code v2.1.169. The first thing you notice is that your old /clear reflex no longer fixes everything. CLAUDE.md is stale, a plugin is shadowing a real command, your MCP server stopped responding, and a hook is silently rewriting every diff. Safe Mode is the kill switch you reach for when /clear only wipes the conversation but the problem lives in your config.
This guide covers the five things --safe-mode actually disables, exactly when to reach for it instead of /clear, and how to enable it in under 10 seconds on macOS, Windows, and WSL — with a triage workflow you can hand a teammate without explanation.
What You Can Do After Enabling Safe Mode (And What You Can't)
Before you run the flag, know which problems it solves and which it leaves on the floor.
| Outcome | Safe Mode | /clear |
Reinstall |
|---|---|---|---|
| Disable a broken CLAUDE.md | ✅ | ❌ | ❌ |
| Disable a misbehaving plugin | ✅ | ❌ | partial |
| Disable hooks rewriting tool output | ✅ | ❌ | ❌ |
| Disable a hung MCP server | ✅ | ❌ | partial |
| Hide bundled skills from the model | ✅ | ❌ | ❌ |
| Wipe runaway conversation context | ❌ | ✅ | ❌ |
| Reset API credentials | ❌ | ❌ | ❌ |
| Reset the model used | ❌ | ❌ | ❌ |
| Reset slash-command history | ❌ | ❌ | ❌ |
| Take less than 10 seconds | ✅ | ✅ | ❌ |
Decision in one sentence: if /clear does not fix it within one or two turns, reach for --safe-mode before you start uninstalling things.
Decision Frame: When to Use Safe Mode (and When NOT)
When to use
- Claude Code starts behaving differently after upgrading from v2.1.16x to 2.1.169 — the upgrade is the only variable, so cancel your customizations to confirm.
- A coworker reports "it works for me, breaks for you" — strip your CLAUDE.md and plugins, see if the bug survives.
- A plugin or MCP server installed in the last 24 hours starts blocking, throwing, or producing wrong tool output — isolate before you uninstall.
- Hooks are silently mutating tool calls and you are not sure which one — turn them all off in one shot.
- You inherit a workstation set up by someone else and want to see the "stock" CLI behavior before opting into anyone's config.
When NOT to use
- You only need to wipe context — use
/clear, do not relaunch. - You only need to swap models — set
ANTHROPIC_MODELor use the model picker, not safe mode. - You suspect a credential issue — safe mode does not touch
ANTHROPIC_API_KEYorANTHROPIC_BASE_URL; check those first. - You want to disable one plugin out of five — edit your settings or the plugin directly; safe mode is all-or-nothing.
- You are mid-task with valuable conversation state — safe mode launches a fresh session, so any work-in-progress context is gone.
Stop rule
If safe mode reproduces the same bug as a normal launch, the problem is not in your customizations. Stop reading this guide, do not waste time pruning plugins, and start looking at the model, network, account, or upstream API.
What --safe-mode Disables: The Five Layers (Verbatim from v2.1.169)
The official v2.1.169 release notes describe the flag in one sentence: "start Claude Code with all customizations (CLAUDE.md, plugins, skills, hooks, MCP servers) disabled for troubleshooting." Each of those five layers maps to a distinct failure mode.
| # | Layer | What gets disabled | Most common failure it fixes |
|---|---|---|---|
| 1 | CLAUDE.md | Project root + parent + ~/.claude/CLAUDE.md global |
Stale instructions overriding the user prompt; contradictory team rules |
| 2 | Plugins | All entries in your plugin directory, including marketplace plugins | Plugin shadowing a built-in command; plugin crashing on cold start |
| 3 | Skills | User-added skills under ~/.claude/skills/. To also hide built-in / bundled skills, combine with CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1
|
Skill being invoked for the wrong intent; skill emitting bad tool calls |
| 4 | Hooks | Every hook event you have registered — across all ~30 documented types (full list in the hooks reference) including PreToolUse, PostToolUse, UserPromptSubmit, Stop, Notification, SessionStart, SessionEnd, PreCompact, SubagentStart/Stop, and the rest |
Hook rewriting diffs or blocking tool calls silently |
| 5 | MCP servers | Every MCP server, whether from settings, --mcp-config, or IDE-typed configs |
MCP server hung on startup; MCP tool list collision; auth loop |
What it does not disable: your API key, the configured base URL (so your ofox endpoint stays live), the model name in ANTHROPIC_MODEL, your conversation history file, your slash-command keybindings, or the trust dialog for the current project.
Layer 1: CLAUDE.md — the silent system prompt extender
CLAUDE.md is loaded from up to three locations on every session start: the project root, every parent directory walked toward /, and your global ~/.claude/CLAUDE.md. Whatever you write there is injected ahead of every user prompt. When safe mode is on, the model behaves as if none of those files exist. This is the first layer to suspect when "the same prompt produces different output today than yesterday" — someone (or you) likely added a new rule in CLAUDE.md that pulls behavior in an unexpected direction.
Layer 2: Plugins — the third-party extension surface
Plugins live in ~/.claude/plugins/ (or your configured plugin directory) and can register slash commands, intercept tool calls, expose new MCP servers, or modify the prompt. Safe mode skips the plugin loader entirely, which means a plugin that crashes on cold start, shadows a built-in command like /clear, or holds a Windows file lock will not appear at all. Plugin issues are the second most common "weird behavior after update" cause after CLAUDE.md.
Layer 3: Skills — both user-added and (optionally) bundled
User-added skills under ~/.claude/skills/ are disabled by safe mode automatically. Bundled skills, workflows, and built-in slash commands are not disabled by safe mode alone — they require the separate CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 env var or disableBundledSkills: true setting (also new in v2.1.169). For most triage you want only safe mode; reach for the bundled-skills flag when you suspect a built-in skill is being chosen over your own logic.
Layer 4: Hooks — the silent tool-call mutators
Hooks fire on dozens of events — PreToolUse, PostToolUse, UserPromptSubmit, Stop, Notification, SessionStart, SessionEnd, PreCompact, SubagentStart/Stop, and more — covering tool calls, session lifecycle, and async events. A hook can rewrite the model's tool input, block a tool from executing, swallow output, or just print extra chatter. They are the hardest layer to debug manually because their effect is silent and out-of-band. Safe mode disables every hook in one shot — usually the fastest way to confirm "is a hook eating my diffs?"
Layer 5: MCP servers — the longest-tail surface
MCP servers come from your settings file, --mcp-config flags, IDE-typed configs, and v2.1.169 enterprise-managed allowedMcpServers/deniedMcpServers policies. They can hang on cold start, collide on tool names, throw auth loops, or simply respond too slowly to be useful. Disabling all of them in one flag lets you ask "would this session work with zero MCP at all?" — a question that is otherwise expensive to answer because most users have between three and ten MCP servers configured.
System Requirements
- Claude Code ≥ v2.1.169 (June 8, 2026). Verify with
claude --version. If you see2.1.168or below, upgrade first:npm install -g @anthropic-ai/claude-codefor the npm install, or run the official installer. - A terminal you can set env vars in: zsh, bash, fish, PowerShell, CMD, or WSL all work.
- Existing API credentials:
ANTHROPIC_API_KEY(or your ofox-style key under the same name) must still be configured. Safe mode disables customizations, not auth. - (Optional) Write access to your shell rc: if you want to persist the flag for a triage session, you will set
CLAUDE_CODE_SAFE_MODE=1in~/.zshrc,~/.bashrc, or PowerShell$PROFILE.
Step-by-Step: Enable Claude Code Safe Mode
Step 1: Confirm your version is v2.1.169 or newer
claude --version
# Expect: 2.1.169 (or higher)
If it returns an older version, run the upgrade matching how you installed it, then relaunch your terminal to make sure the new binary is on your PATH.
Step 2: Launch with the flag (one-shot)
macOS / Linux / WSL:
claude --safe-mode
Windows PowerShell:
claude --safe-mode
Windows CMD:
claude --safe-mode
The flag is the same everywhere; only the shell wrapping changes. The session that opens will skip every CLAUDE.md, plugin, skill, hook, and MCP server.
Step 3: (Alternative) Persist with the env var for a triage session
When you want every claude invocation in a shell to be safe — useful when you are debugging across multiple panes or repos:
macOS / Linux / WSL (bash, zsh):
export CLAUDE_CODE_SAFE_MODE=1
claude
Windows PowerShell:
$env:CLAUDE_CODE_SAFE_MODE = 1
claude
Windows CMD:
set CLAUDE_CODE_SAFE_MODE=1
claude
Verify the env var is live before you launch:
echo $CLAUDE_CODE_SAFE_MODE
# Expect: 1
Step 4: Confirm safe mode is active
Once in the session, type a prompt that should trigger a project rule from your CLAUDE.md. If the rule is ignored, safe mode is on. You can also list your loaded MCP servers — the list should be empty.
Step 5: Exit safe mode cleanly
For a one-shot launch, just /quit and start claude again without the flag.
For the env-var path, unset it before you relaunch:
# macOS / Linux / WSL
unset CLAUDE_CODE_SAFE_MODE
# PowerShell
Remove-Item Env:CLAUDE_CODE_SAFE_MODE
# CMD
set CLAUDE_CODE_SAFE_MODE=
Then check your rc files (~/.zshrc, ~/.bashrc, $PROFILE) for a stale export that would re-arm safe mode on the next shell. This is the single most common reason people report "Claude Code still ignores my CLAUDE.md" days after they thought they had turned safe mode off.
Step 6: The 3-step triage workflow
Once safe mode confirms the bug is in your customizations, narrow it down with a binary-search pattern instead of un-installing everything at once:
- Relaunch normally, keep
CLAUDE.mdand plugins, manually disable hooks and MCP via settings. Reproduce? If yes, the culprit is in CLAUDE.md or a plugin — usually the larger and more recent layer. - Re-enable hooks, keep MCP off. Reproduce? If yes, the culprit is a hook. Disable hooks one at a time; v2.1.169 hooks are evaluated in load order, so disable the most recently added hook first.
- Re-enable MCP servers one by one. The one that reintroduces the bug is your suspect. Restart the session between each MCP toggle — MCP servers cache their tool list at session start, so live toggling without a restart can give you a false negative.
You almost never need step 3 to finish — the bug usually surfaces by step 1 or 2. Step 3 only matters when you run many MCP servers, which is increasingly common in larger teams.
Step 7: Capture a clean repro for the bug tracker
After you have identified the offending layer, run safe mode one more time with the single offending file copied into place. This isolates the bug to one customization and gives you a tight repro to file. The repro should fit in two lines: "I added ~/.claude/plugins/foo/index.ts, with safe mode I get behavior A, with that plugin re-enabled I get behavior B." This is the format the Claude Code maintainers respond to fastest.
Common Errors During Safe Mode Setup (and Fixes)
| Symptom | Root cause | Fix |
|---|---|---|
Unknown flag: --safe-mode |
Claude Code is on v2.1.168 or older | Upgrade to v2.1.169+, relaunch terminal so PATH picks up the new binary |
| Safe mode "doesn't seem to do anything" — CLAUDE.md still applies | Two claude binaries on PATH; older one wins |
which claude (Mac/Linux) or where claude (Windows); remove or rename the older copy |
CLAUDE.md still loads despite the flag |
You confused --safe-mode with /clear; you ran /clear inside an already-loaded session |
Quit the session entirely (Ctrl-D or /quit), then relaunch with the flag |
| MCP servers still appear in the slash-command list | Stale plugin cache on Windows (a known v2.1.169 fix for MCPB plugin cache) | Quit, delete the MCPB plugin cache directory, relaunch with --safe-mode
|
claude -p hangs forever on Windows after enabling safe mode |
Unrelated regression already fixed in v2.1.169 (skill-scan stall) | Confirm you are on >=2.1.169; if so, file an issue with --verbose output |
CLAUDE_CODE_SAFE_MODE set but env var has spaces around =
|
Bash treats CLAUDE_CODE_SAFE_MODE =1 as a command, not an assignment |
export CLAUDE_CODE_SAFE_MODE=1 with no spaces — strict, no shortcuts |
| Safe mode disables your hook that does mandatory pre-commit signing — now your commits are unsigned | Working as designed; safe mode is for diagnosis, not for everyday work | Exit safe mode before any commit you intend to push; reserve safe mode for read-only triage |
Enterprise managed allowedMcpServers list still seems "active" |
Safe mode disables MCP servers, not the policy schema parser; policy text remains in settings | Treat the policy file as dormant in safe mode — it is parsed but no MCP servers run |
Team / Multi-Developer Configuration
Safe mode is the cleanest reproducibility primitive your team has when a bug report comes in. Wire it into your runbook.
Shared triage alias
Drop a one-liner into your team's dotfiles repo so every engineer has the same entry point:
# ~/.zshrc or ~/.bashrc, committed to the team's dotfiles repo
alias claude-triage='CLAUDE_CODE_SAFE_MODE=1 claude'
When a teammate reports a Claude Code bug, the first request from the on-call is "run claude-triage, paste the repro." That is one command, no context, no version drift.
Triage matrix
| Bug surface | Reporter runs | Expected if bug is in their config | Expected if bug is upstream |
|---|---|---|---|
| Tool output looks rewritten |
claude-triage then repro |
Bug disappears → hook is the culprit | Bug persists → model / API issue |
| Slash command shadowed |
claude-triage then /help
|
Built-in command reappears → plugin is shadowing | Command still missing → CLI bug |
| CLAUDE.md rules ignored |
claude-triage then ask a question only the rule would answer |
Behavior identical → your CLAUDE.md was unreachable anyway (path issue) | Behavior changes only in safe mode → CLAUDE.md was loading but losing |
| MCP tool returns errors |
claude-triage then attempt task |
Task succeeds without MCP → server is broken | Task fails the same way → not an MCP issue |
CI / scripts: don't ship safe mode
--safe-mode is a diagnostic flag, not a deploy target. Do not add it to your CI invocations of claude -p or claude agents — you will silently lose your team's CLAUDE.md, hooks, and any MCP integrations your CI relies on. If you suspect CI is hitting a customization bug, run safe mode locally to confirm, then patch the offending customization. A --safe-mode line in a CI YAML file is an outage waiting to happen — keep the flag where humans can see it.
Onboarding new hires
For day-one onboarding, give the new engineer a 5-minute exercise: run claude-triage, ask the same question they ask in normal mode, observe the difference. They walk away knowing what their team's customizations actually do — instead of treating CLAUDE.md as magic that just happens.
Advanced: Pair Safe Mode with disableBundledSkills and /cd
v2.1.169 shipped three related controls, and they compose well.
--safe-mode + CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1
--safe-mode disables user-added skills under ~/.claude/skills/. To also hide the built-in / bundled skills, workflows, and built-in slash commands from the model, set CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 (or disableBundledSkills: true in your settings). Combined, the model sees a CLI with nothing on top — useful when you want to compare "stock model behavior" against your customized behavior.
CLAUDE_CODE_SAFE_MODE=1 CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 claude
Safe mode + /cd
v2.1.169 also added /cd to switch the session's working directory without breaking the prompt cache mid-session. Combine the two when you triage across repos: launch with --safe-mode once, then /cd between repositories. You only pay the cold-start cost once and your triage stays on the same model context window.
Safe mode + an ofox-style upstream
If you route Claude Code through a multi-provider gateway like ofox — using ANTHROPIC_BASE_URL=https://api.ofox.ai/anthropic — safe mode keeps the routing intact while still neutralizing every local customization. That separation is the whole point: you can rule out local config without touching your upstream credentials. Safe mode is the one CLI flag that lets you ask "is it me or is it everything I added on top?" — and get an honest answer in under ten seconds.
For deeper config patterns once you are past triage, see the Claude Code ofox configuration guide, the Claude Code hooks, subagents, and skills guide, and the Claude Code safety guide for preventing accidental file deletion — all three lean on the customization layers safe mode disables.
Related Reading on Claude Code Setup
- For the broader CLI permission model, see the Claude Code token optimization guide — the customizations safe mode disables are the same ones that drive token cost.
- If you are still picking between CLIs, the Claude Code vs Codex vs Cursor vs DeepSeek TUI comparison lays out which has a comparable triage flag.
- For the "Go to Sleep" / model-stops bug that often gets confused with a customization failure, see the Claude "Go to Sleep" bug explainer — safe mode does not fix model-side issues.
- For multi-tool setups, the Cursor + Claude Code + Cline custom API setup guide shows how the same
ANTHROPIC_BASE_URLpattern survives safe mode.
Originally published on ofox.ai/blog.
Top comments (0)