You plan. You think the model is only proposing changes. Then it runs rm — and you never saw the prompt.
That is the gap Claude Code v2.1.212, shipped July 17, 2026, quietly closed. Tucked into the release notes under “What’s changed” is this line:
Fixed plan mode auto-running file-modifying Bash commands (e.g.
touch,rm) without a permission prompt or SDKcanUseToolcallback.
No CVE. No advisory. No loud “security update” banner. Just a one-liner in a routine release. But for anyone who runs Claude Code in plan mode — which is the recommended default for safe, review-before-act workflows — this is one of the more important fixes to land in recent weeks, because it inverts the core promise of plan mode.
The promise of plan mode
Plan mode is supposed to be the safe room. You tell the agent to figure out an approach, it sketches a diff, and nothing on disk changes until you approve. The whole point is that file mutations require an explicit go-ahead — either an interactive permission prompt or, in headless/SDK use, a canUseTool callback you control.
That contract is what lets teams point Claude Code at a real repo, switch to plan mode, and walk away from the keyboard without fear of a stray rm -rf mid-reasoning.
What was actually happening
According to the v2.1.212 release notes, plan mode was auto-running file-modifying Bash commands — the notes name touch and rm explicitly — without raising a permission prompt and without firing the SDK canUseTool callback.
Translate that:
- In interactive use, commands that should have stopped and asked you (“Allow Bash:
rm tmp/x?”) instead executed silently. - In SDK/headless use, commands that should have been gated by your
canUseToolhandler instead bypassed it.
touch sounds harmless until you realize it can create files, clobber timestamps, and prepare state the agent later acts on. rm needs no elaboration. The changelog only names two commands as examples — the wording (“e.g.”) implies the class of affected commands is broader, and that the fix is about the gating path, not a per-command blocklist.
This is a classic fail-open bug. The safe default (ask first) was not applied, and the failure was silent — no error, no log line you would have noticed, no prompt you could have declined.
Who was exposed
- Anyone on Claude Code v2.1.211 or earlier who used plan mode with Bash access enabled. Releases 2.1.209 through 2.1.211 are the immediately preceding versions and all predate the fix.
- SDK/automation operators who relied on
canUseToolto enforce policy in plan mode. If your guardrail was “reject any destructive Bash in plan mode,” it was being skipped. - Teams that ship Claude Code inside CI or agent pipelines where plan mode is used as a sandboxing layer. The bypass undermines the sandbox assumption.
Notably, this matters most for the people doing everything right: using plan mode precisely because they wanted a non-destructive review step. The bug turned the safety feature into a blind spot.
Two more v2.1.212 boundary fixes worth your attention
The plan-mode bypass wasn’t the only safety edge closed in this release. Two others matter if you run Claude Code anywhere it can touch the filesystem or run headless:
Worktree creation could escape the repository. The same notes also ship this fix:
Fixed worktree creation following a repository-committed symlink at
.claude/worktrees, which could create files outside the repository.
That is a symlink-traversal escape. If someone — or a prior agent run — commits a symlink inside .claude/worktrees, Claude Code’s worktree setup would follow it and write files outside the repo root, beyond the directory you scoped the agent to. That defeats directory-level containment, which is exactly what teams rely on to keep an autonomous agent in a box. It is the same “the path I trusted was not the path that was used” class of bug as the absolute-path permissions.deny failure linked below. If you use worktrees (or let Claude create them), treat any committed symlink under .claude/ as untrusted input — and don’t scope an agent’s blast radius on the assumption that .claude/ is inert.
SIGTERM now actually kills the process tree. In print/SDK mode, a SIGTERM arriving during a running Bash tool used to orphan the command’s process tree — the agent turned away, the child processes kept running, and the CLI never reaped them. v2.1.212 changes that: the CLI now aborts the turn, kills the tree, and exits 143. If you run Claude Code inside containers, CI, or a supervisor that sends SIGTERM on timeout or cancellation, orphaned processes were a quiet resource leak and a stuck-build footgun. This is distinct from the mid-write SIGKILL git-corruption hazard (linked below): that one is about data integrity mid-commit; this one is about process hygiene on shutdown.
How to confirm you’re patched
- Update to v2.1.212 or later:
claude --version # should report 2.1.212+ npm i -g @anthropic-ai/claude-code@latest - In plan mode, ask Claude to run a file-modifying command like
touch /tmp/cc-plan-test. You should now see a permission prompt (or an SDKcanUseToolcall) — not a silent execution. - If you run headless, assert in your
canUseToolhandler that plan-mode Bash requests are intercepted and logged, and add a test that fails if they are not. - If you use worktrees, drop a symlink under
.claude/worktreespointing outside the repo and confirm v2.1.212 no longer writes through it. On older versions this is an escape, not a warning. - If you orchestrate via a supervisor, send SIGTERM to a Claude Code process mid-Bash and confirm the child tree is reaped (no lingering processes after exit 143).
Why “no advisory” is the real story
The fact that this shipped as an ordinary changelog line is the angle worth holding onto. Permission-bypass fixes in an agent that can execute shell commands are materially different from a UI tweak, yet they get the same release treatment as “fixed Ctrl+J inserting a newline.” If you only read the headline version bumps, you will miss the fixes that actually move your risk posture.
This is now the fourth time in recent weeks a Claude Code permission/safety boundary has warranted a Beware. The earlier ones are worth reading together:
- Beware: Claude Code’s permissions.deny Silently Fails on Absolute Paths — your credential guard may be a no-op.
- Beware: Claude Code’s disallowedTools Don’t Reach Subagents — your deny list is parent-only.
- Beware: Claude Code’s Approval Preview Could Be Unicode-Spoofed (v2.1.211) — the sibling fix one release earlier.
- Beware: Claude Code’s Background Tasks Can SIGKILL Mid-Write and Corrupt Git — long-running task hazards.
Takeaway
Update to v2.1.212 today if you use plan mode, worktrees, or run Claude Code under a supervisor — all three were affected. And stop treating “patch notes” as noise: for a shell-executing agent, a one-line “fixed auto-running Bash” or “fixed worktree creation following a symlink” entry is a security bulletin in disguise. Read every release’s “Fixed” section, and build your own regression test for the permission boundaries you depend on — because the gaps were shipping silently, and the next one might be too.