Claude Code 2.1.169 Adds Safe Mode Because Agent Customization Finally Needs a Circuit Breaker

Claude Code 2.1.169 Adds Safe Mode Because Agent Customization Finally Needs a Circuit Breaker

Claude Code v2.1.169 is not a feature release pretending to be a platform shift. It is something more useful: a runtime admitting it has become complex enough to need a circuit breaker.

The headline addition is --safe-mode, also available through CLAUDE_CODE_SAFE_MODE. When enabled, Claude Code starts with CLAUDE.md, plugins, skills, hooks, and MCP servers disabled. That sounds like a troubleshooting flag. It is really a maturity marker. The serious version of a coding agent is no longer “model plus terminal.” It is a programmable runtime assembled from project memory, local automation, remote tools, policy files, telemetry, IDE state, and background workers. Once that much behavior can be injected into a session, a clean boot path stops being optional.

The release landed June 8 as v2.1.169. During research, the anthropics/claude-code repository had 131,226 stars, 21,262 forks, 8,588 open issues, and had been pushed the morning after the release. The release shipped 10 binary assets with about 1,000 total downloads at the time checked, led by Windows x64 at 418 downloads and Linux x64 at 178. Those numbers are not the story by themselves, but they do point at the shape of the install base: Claude Code is broad enough now that runtime hygiene affects real teams, not just early adopters stress-testing a demo.

Safe mode is the agent equivalent of booting without extensions

Browsers have safe mode. Editors have extension-disabled startup. Kubernetes operators eventually learn they need a way around the clever admission webhook when the control plane catches fire. Coding agents need the same primitive because their behavior is composed from too many layers to debug by vibes.

If Claude Code starts producing strange edits, making unexpected tool calls, ignoring project conventions, or hanging during startup, the wrong first question is “did the model get worse?” The better first question is “which customization changed the runtime?” A serious Claude Code setup may include repository instructions in CLAUDE.md, third-party skills, local hooks, plugins, MCP servers, IDE integration, browser control, background agents, managed enterprise settings, cloud-provider routing through Bedrock, Vertex, or Foundry, and telemetry hooks. Any one of those can be useful. Any one can also be the source of a haunted session.

--safe-mode gives teams a fast binary split: does the behavior reproduce when all of those runtime extensions are disabled? If yes, keep investigating the core runtime, model path, or prompt. If no, re-enable customizations in layers: project memory first, then hooks, then MCP, then skills and plugins. That is not glamorous. It is how incidents become diagnosable instead of folkloric.

The addition also changes how teams should write support docs. “Try again” is not an incident runbook. “Reproduce with claude --safe-mode, capture the output, then re-enable extensions one category at a time” is. Platform teams rolling Claude Code out internally should add that flow to onboarding, bug templates, and escalation playbooks now, before the first confusing agent failure gets misclassified as a model problem.

The MCP fixes are where policy meets startup reality

The release also tightens enterprise MCP policy enforcement. Anthropic calls out fixes for allowedMcpServers and deniedMcpServers across reconnects, IDE-typed configs, --mcp-config servers during the first session after install, and the period before remote settings load. That list is more interesting than it looks because it names the exact places where agent security tends to fail: startup, reconnect, cached state, pre-warmed workers, and cross-surface handoffs.

A policy that applies only after the happy-path session settles is not a policy. It is a suggestion with a loading spinner. MCP servers are tool surfaces; they can bridge a model to data stores, internal services, browsers, shells, issue trackers, or custom company systems. If a deny rule behaves differently on reconnect than it does on a fresh launch, or if a first-run --mcp-config path can slip through before managed settings arrive, the runtime has created an early-session policy gap. Attackers and accidents both love gaps.

This matters most for enterprises because Claude Code is increasingly being treated as developer infrastructure. The same organization that would never let an editor extension arbitrarily connect to internal systems may accidentally allow a coding agent to do just that through MCP configuration drift. The right model is not “do we trust Claude?” It is “which tool endpoints are available, under what policy, from which workspace, with which identity, and at what point in the session lifecycle?” v2.1.169 is a reminder that policy enforcement has to be temporal, not just declarative. It must hold during startup, reconnect, remote settings load, and worker wake-up.

The managed-settings change follows the same operational logic. Remote-managed settings with one invalid entry now apply the remaining valid policies and surface the validation error, rather than silently dropping the entire payload. That is the safer failure mode. Rejecting everything because one value is malformed creates a cliff where a typo in a noncritical setting can accidentally remove unrelated enforcement. Applying the valid subset is less elegant, but production systems should prefer partial policy continuity over all-or-nothing fragility.

Telemetry config is part of the security boundary

Another small line deserves attention: untrusted project settings can no longer set OpenTelemetry client-certificate paths without trust confirmation. This is exactly the kind of fix people skip in release notes because it does not say “remote code execution” in neon letters.

But client certificates are credentials. Observability plumbing is not harmless just because it lives near dashboards instead of shell commands. If repo-local settings can redirect an agent toward certificate paths without a trust decision, telemetry becomes a credential-routing surface. The practical lesson is broader than Claude Code: every configuration path that can point at credentials, sockets, files, or external endpoints belongs inside the security model. “It is just logging” has caused enough incidents to retire the phrase.

v2.1.169 also adds a disableBundledSkills setting and CLAUDE_CODE_DISABLE_BUNDLED_SKILLS, which hide bundled skills, workflows, and built-in slash commands from the model. That is useful for regulated or tightly scoped environments where the desired agent surface is narrower than the default product surface. Treat it as a policy control, not a cosmetic preference. If a team wants Claude Code to perform one class of work in CI or on a locked-down workstation, reducing the available action vocabulary is a feature.

Background agents are becoming stateful infrastructure

The rest of the release reads like runtime gardening, which is usually where the expensive bugs live. Background-agent fixes preserve flags like --ide, --chrome, --bare, and --remote-control across retire and wake. Respawn-state validation is hardened. Project-level env values now apply correctly on pre-warmed workers. Shared-checkout handling avoids a wasted rejected edit before EnterWorktree. The claude agents --json output now includes blocked and newly dispatched sessions, adds --all for completed sessions, and exposes id and state fields.

That is not launch-stage glitter. It is what happens when background agents stop being toys and start becoming processes people expect to resume correctly. If a worker wakes up without the flags it had before retirement, the runtime has changed underneath the user. If JSON state does not include blocked or newly dispatched sessions, automation cannot build accurate dashboards or cleanup jobs. If project-level environment values are ignored by pre-warmed workers, the failure may appear nondeterministic: fresh sessions behave one way, warm sessions another. That is how infrastructure loses trust.

The restored default five-minute idle timeout for Vertex and Foundry streams belongs in the same bucket. Long-running model streams need failure semantics. A stream that stalls forever is not patient; it is ambiguous. Anthropic allows opting out with API_FORCE_IDLE_TIMEOUT=0, which is fine for teams that know they need it. The default should protect ordinary users from quietly stuck work.

For practitioners, the action list is straightforward. Upgrade if your team uses MCP, hooks, skills, plugins, background agents, managed settings, remote control, or cloud-provider backends. Add claude --safe-mode to incident response. Test MCP allow and deny rules across first run, reconnect, IDE config, and managed-settings load. Review whether untrusted repositories can influence telemetry paths, environment variables, or tool configuration. Use disableBundledSkills where a narrower action surface is part of the security posture. If you run Vertex or Foundry, verify that the restored five-minute timeout matches your workload instead of assuming every stalled stream deserves infinite patience.

The broader read is simple: Claude Code is maturing from coding assistant into agent runtime. Agent runtimes need boring controls: safe boot, deterministic policy enforcement, explicit state, credential-path hardening, timeout behavior, and clean JSON for automation. None of this is flashy. All of it is the difference between a clever tool and supportable developer infrastructure. LGTM.

Sources: Anthropic Claude Code v2.1.169 GitHub release, Claude Code settings docs, Claude Code MCP docs, Claude Code GitHub Actions docs, GitHub issue #66358