Tutorials
Ren Okabe14 min read73 views

Claude Code Plan Mode: How It Actually Gates Your Edits (2026)

Plan mode is not a read-only state. It is a rule at step 4 of a six-step permission evaluation, which is why allow rules stop applying while you plan and why a session with bypass permissions can edit anyway. The CLI keystrokes, the settings, the Agent SDK equivalent, and a plan-then-execute pipeline in Python and TypeScript. August 2026.

Updated on August 23, 2026

Two people sketching a plan on paper between two open laptops, August 2026
Two people sketching a plan on paper between two open laptops, August 2026
On this page

Quick answer

As of August 2026, plan mode is not a read-only state. It is a rule at step 4 of Claude Code's six-step permission evaluation: while the mode is plan, file-edit and shell-write tools are routed to a confirmation step regardless of any allow rule you have configured, so writes cannot be auto-approved while Claude is still planning. Enter it with Shift+Tab, by prefixing one prompt with /plan, or by starting the session with claude --permission-mode plan. Make it a project default with {"permissions": {"defaultMode": "plan"}} in .claude/settings.json. In the Agent SDK the same mode is permission_mode="plan" (Python) or permissionMode: "plan" (TypeScript), and you can switch out of it mid-session. One important exception: in sessions where bypass permissions are available, plan mode's blocks are not enforced at all.

Most guides for this feature describe the keystroke and stop there. That is enough to use plan mode by hand and not enough to predict what it will do, which is why people are regularly surprised when a "read-only" planning session runs a shell command, or when a carefully written allow rule turns out not to apply.

Anthropic logo This tutorial covers Claude Code, the CLI, and the Claude Agent SDK, because plan mode exists in both and behaves slightly differently in each. Every version-dependent claim below carries the version number it applies to, so you can tell when this page has gone stale.

Where plan mode actually sits

Claude Code evaluates a tool request in six ordered steps. Per the Agent SDK permissions documentation (retrieved August 21, 2026), the order is:

1. Hooks              -> can deny outright, or pass on
2. Deny rules         -> block, even in bypassPermissions
3. Ask rules          -> force a confirmation
4. Permission mode    -> plan / acceptEdits / bypassPermissions act here
5. Allow rules        -> approve a match
6. canUseTool         -> whatever is still unresolved

Plan mode acts at step 4, and this is the detail worth internalising: in plan mode, file-edit and shell-write tools are routed to step 6 regardless of allow rules. Step 5 never gets the chance to approve them. The documentation states it directly: plan "routes file-edit and shell-write tools to your canUseTool callback regardless of allow rules, so write operations cannot be auto-approved while planning."

That is a meaningfully different claim from "plan mode is a read-only state". Read-only would mean the tools are gone. They are not gone, they are re-routed, and the practical consequences follow from that:

  • An allow rule such as Edit(src/**) that works in every other mode does nothing while you are planning.
  • A PreToolUse hook still runs first, at step 1, and can still deny.
  • A deny rule still applies, because deny is evaluated at step 2 before the mode is consulted.

Prerequisites

  • Claude Code v2.1.228 or later on macOS, Linux or WSL, or v2.1.233 or later on native Windows, if you want the version whose built-in starting mode is auto mode. Check with claude --version.
  • For the SDK sections, @anthropic-ai/claude-agent-sdk (TypeScript) or claude-agent-sdk (Python).
  • Several behaviours below changed between v2.1.212 and v2.1.233. If you are on an older build, the notes say what you will see instead.

Enter plan mode

Three ways, all current as of August 2026 per the permission modes documentation:

bash
# For a whole session, from the shell
claude --permission-mode plan

Inside a running session, press Shift+Tab to cycle modes, or prefix a single prompt with /plan to plan just that one turn. The status bar shows ⏸ plan mode on when you are in it. Pressing Shift+Tab again leaves plan mode without approving anything.

The cycle order matters if you are counting keypresses. Starting from auto mode, the first Shift+Tab press switches to default, and the cycle then runs default to acceptEdits to plan and back to default. Optional modes slot in after plan.

Know which mode your session actually started in

This is the most common source of "plan mode is not working" confusion, so it is worth being precise. Claude Code takes the starting mode from the first of these that applies:

  1. The --permission-mode flag, or --dangerously-skip-permissions
  2. permissions.defaultMode in a settings file
  3. The built-in default

On Pro, Max and Team plans the built-in starting mode is auto mode, on the versions named in the prerequisites. On earlier builds it is Manual.

A resumed session keeps whatever mode it was in, unless you pass --permission-mode or --dangerously-skip-permissions again.

Make plan mode the project default

To have every terminal session in a repository start in plan mode, put this in .claude/settings.json and commit it:

json
{
  "permissions": {
    "defaultMode": "plan"
  }
}

Visual Studio Code logo Two caveats that cost people time. First, conversations started by the VS Code extension do not read project settings for the starting permission mode; there you set claudeCode.initialPermissionMode to plan in your VS Code user settings instead. Second, and this one is genuinely surprising: a defaultMode of "auto" does not take effect from .claude/settings.json or .claude/settings.local.json. Other values, including "plan", apply from any settings file. So the file above works, but the same file with "auto" silently does not.

Review and approve the plan

When the plan is ready, Claude presents it and asks how to proceed. The options are:

  • Yes, and use auto mode. Approve and start in auto mode. When auto mode is unavailable this option instead reads "Yes, auto-accept edits".
  • Yes, manually approve edits. Approve and review each edit individually.
  • No, keep planning. Stay in plan mode and say what to change.

Two keystrokes here that are not widely known. Ctrl+G opens the proposed plan in your default text editor so you can edit it directly before Claude proceeds, which is far faster than describing the change in prose. And when the showClearContextOnPlanAccept setting is enabled, the list gains a first option that approves the plan and clears the planning context, so execution starts on a clean context window.

Approving a plan exits plan mode and switches the session to whichever mode the option you picked describes. Accepting also names the session automatically from the plan content, unless you already set a name with --name or /rename. To plan again later, cycle back with Shift+Tab or prefix the next prompt with /plan.

The two exceptions that break the "it cannot edit" assumption

Shell commands during planning

Claude runs shell commands while planning, to explore. What gates them depends on a different mode's availability. When auto mode is available and the useAutoModeDuringPlan setting is on, which it is by default, the classifier reviews shell commands during planning instead of prompting you: approved commands run, rejected ones are blocked. Otherwise, commands outside the built-in read-only set prompt for approval.

Note the version history, because it explains conflicting reports online: in v2.1.212 through v2.1.217, sessions without bypass permissions prompted for every command outside the read-only set whether or not auto mode was available.

One related asymmetry: the Bash sandbox and auto mode normally combine, but not in plan mode, where the sandbox's auto-allow mode does not widen approvals.

Sessions with bypass permissions available

This is the exception that invalidates the flat claim that plan mode cannot change your files. In sessions where bypass permissions are available, Claude Code does not enforce plan mode's blocks. Claude is still instructed to plan without editing, but a file edit or shell command it attempts during planning runs without prompting. Explicit ask rules, and rm or rmdir removals targeting a critical path, still prompt.

Writes to protected paths such as .git and .claude are never auto-approved in any mode, with two exceptions: bypassPermissions mode, and plan-mode sessions where bypass permissions are available.

So if you are relying on plan mode as a safety boundary rather than as a workflow aid, check how the session was started. If bypass permissions are in the mode cycle, plan mode is a suggestion to the model, not an enforced gate.

Plan mode in the Agent SDK

Here is where plan mode becomes something you can build with rather than just type. The SDK exposes the same six modes: default, dontAsk, acceptEdits, bypassPermissions, plan and auto.

Python logo Set it at query time in Python:

python
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions


async def main():
    async for message in query(
        prompt="Propose a migration plan for the auth module",
        options=ClaudeAgentOptions(
            permission_mode="plan",
        ),
    ):
        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

TypeScript logo And in TypeScript:

typescript
import { query } from "@anthropic-ai/claude-agent-sdk";

async function main() {
  for await (const message of query({
    prompt: "Propose a migration plan for the auth module",
    options: {
      permissionMode: "plan"
    }
  })) {
    if ("result" in message) {
      console.log(message.result);
    }
  }
}

main();

In plan mode, file edits are never auto-approved even when an allow rule matches; they reach your canUseTool callback instead. On v2.1.212 or later, shell commands that modify files, such as touch and rm, reach the callback the same way. Claude may also use AskUserQuestion to clarify requirements before finalising the plan, so a non-interactive harness needs to handle that.

Build a plan-then-execute pipeline

The interactive approval prompt has a programmatic equivalent: start the session in plan, inspect what came back, then switch modes to execute. Python, using the streaming client:

python
import asyncio
from claude_agent_sdk import ClaudeSDKClient, ClaudeAgentOptions


async def main():
    async with ClaudeSDKClient(
        options=ClaudeAgentOptions(
            permission_mode="plan",  # phase 1: propose only
        )
    ) as client:
        await client.query("Plan the migration of auth/ to the new session store")

        plan = []
        async for message in client.receive_response():
            if hasattr(message, "result"):
                plan.append(message.result)

        # Your gate. Log it, diff it, send it for review, or reject it.
        if not approve(plan):
            return

        # phase 2: let it act
        await client.set_permission_mode("acceptEdits")
        await client.query("Implement the plan you just proposed.")
        async for message in client.receive_response():
            if hasattr(message, "result"):
                print(message.result)


def approve(plan):
    return bool(plan) and "auth/" in "\n".join(plan)


asyncio.run(main())

The TypeScript equivalent uses setPermissionMode() on the query object:

typescript
import { query } from "@anthropic-ai/claude-agent-sdk";

const q = query({
  prompt: "Plan the migration of auth/ to the new session store",
  options: { permissionMode: "plan" }
});

// ... consume the planning phase, apply your own gate ...

await q.setPermissionMode("acceptEdits");

The reason to do this in code rather than by hand is that your approval gate can be anything: a schema check on the plan, a diff against a change budget, a second model reviewing it, or a human in a queue. The CLI gives you three fixed options. A pipeline gives you your own.

One caveat worth knowing before you reach for canUseTool as your gate: a tool call approved at an earlier step never reaches it. In the TypeScript SDK, passing canUseTool in a configuration where the evaluation order auto-approves calls first emits a process warning with the code CLAUDE_SDK_CAN_USE_TOOL_SHADOWED. If you need a check that runs on every call regardless of mode and rules, use a PreToolUse hook, which is evaluated at step 1.

Plan mode and subagents

Subagents inherit the parent session's permission mode. An AgentDefinition's own permissionMode can override that, except when the parent is using bypassPermissions, acceptEdits or auto: those apply to every subagent and cannot be overridden per subagent.

The practical consequence is the one that catches people building delegation trees: you cannot reliably pin a "research only, never edits" planning subagent underneath a parent running in auto mode. The parent's mode wins. If the planning boundary matters, put it on the parent session, or enforce it with a PreToolUse hook, which no mode can override. If you are building out delegation, our tutorial on creating and scoping Claude Code subagents covers the file format and the nesting and concurrency caps.

Use a bigger model for planning only

A frequent question on this topic is how to plan with Opus but execute with something cheaper. There is a built-in model alias for exactly that. Per the model configuration documentation, opusplan "uses opus during plan mode, then switches to sonnet for execution".

bash
claude --model opusplan --permission-mode plan

The plan-mode Opus phase uses the same context window as the opus setting. On subscription tiers where Opus is automatically upgraded to 1M context, opusplan gets that upgrade in plan mode too; to force 1M context for both phases when you are not on an auto-upgrade tier, set the model to opusplan[1m]. If you route through a gateway, ANTHROPIC_DEFAULT_OPUS_MODEL sets the model used for the plan phase and ANTHROPIC_DEFAULT_SONNET_MODEL the one used outside it.

The full mode table

For reference, all six modes as documented in August 2026, with what each runs without asking:

Scroll to see more

ModeRuns without askingUse for
default (labeled Manual)Reads onlyReviewing every action, sensitive work
acceptEditsReads, file edits, common filesystem commandsIterating on code you are reviewing
planReads, plus classifier-approved commands when auto mode is availableExploring before changing
autoEverything, with background safety checksLong tasks, fewer prompts
dontAskOnly pre-approved toolsLocked-down CI and scripts
bypassPermissionsEverythingIsolated containers and VMs only

auto and dontAsk are recent additions and are absent from most of the plan-mode writing currently circulating, which predates them. If you want a hard, non-prompting boundary for automation, dontAsk is usually the mode you actually want rather than plan, because it denies instead of prompting:

bash
claude -p "run the test suite" --permission-mode dontAsk --allowedTools "Bash(npm test)" "Read"

Common mistakes

  • Treating plan mode as an enforced sandbox. It is not, in sessions where bypass permissions are available. Use isolation for isolation.
  • Expecting allow rules to apply while planning. File-edit and shell-write tools skip step 5 entirely in plan mode.
  • Putting "defaultMode": "auto" in .claude/settings.json. It is ignored there, silently. Project settings do work for "plan".
  • Expecting the VS Code extension to read the project default. It does not, for the starting mode. Set claudeCode.initialPermissionMode.
  • Pinning permissionMode on a planning subagent under an auto-mode parent. The parent wins.
  • Using canUseTool as a universal gate. Anything auto-approved earlier never reaches it. Use a PreToolUse hook.
  • Reading a pre-2026 guide's mode list. If it names three modes, it is missing half of them.

FAQ

How do I get into plan mode in Claude Code?
Press Shift+Tab to cycle to it, prefix a single prompt with /plan, or start the session with claude --permission-mode plan. The status bar reads ⏸ plan mode on. To make it the default for a project, set {"permissions": {"defaultMode": "plan"}} in .claude/settings.json.

How do I get out of plan mode?
Press Shift+Tab again to leave without approving anything, or approve the plan when Claude presents it. Approving exits plan mode and moves the session into the mode named by the option you chose.

What is the difference between plan mode and edit mode?
Plan mode routes file-edit and shell-write tools to a confirmation step regardless of allow rules, so writes cannot be auto-approved while planning. acceptEdits, the closest thing to an "edit mode", does the opposite: it auto-approves file edits and common filesystem commands such as mkdir, touch, mv and cp inside the working directory.

Can Claude edit files in plan mode?
Not in a normal session; edits are blocked until you approve the plan. But in sessions where bypass permissions are available, plan mode's blocks are not enforced, and an edit Claude attempts while planning will run. That exception is the reason to treat plan mode as a workflow aid rather than a security boundary.

Does Claude run shell commands in plan mode?
Yes, to explore. When auto mode is available and useAutoModeDuringPlan is on, which is the default, the classifier reviews those commands rather than prompting you. Otherwise anything outside the built-in read-only set prompts.

How do I use plan mode with the Claude Agent SDK?
Pass permission_mode="plan" in Python or permissionMode: "plan" in TypeScript. To switch out mid-session, call set_permission_mode() or setPermissionMode(). File edits reach your canUseTool callback rather than being auto-approved.

How does opus plan mode work in Claude Code?
Set the model to opusplan. It uses Opus while you are in plan mode and switches to Sonnet for execution. Use opusplan[1m] to force the 1M context window across both phases.

Do subagents inherit plan mode?
Yes. Subagents inherit the parent session's permission mode, and an AgentDefinition's permissionMode can override it except when the parent is in bypassPermissions, acceptEdits or auto, which always apply to every subagent.

Limitations and open questions

  • Plan durability is not documented. Armin Ronacher's reverse-engineering of plan mode (December 2025) reports that a plan is written as a markdown file into a plans folder, which suggests plans outlive the turn that produced them. The published documentation does not describe that surface, so treat it as an observed implementation detail rather than a stable contract.
  • The classifier's planning-phase decisions are not enumerable. With useAutoModeDuringPlan on, whether a given shell command runs during planning is a model decision. There is no static list to check against, which makes plan-mode behaviour hard to assert in a test.
  • No documented programmatic equivalent of the approval prompt. The SDK gives you the mode and canUseTool, so you can reconstruct a gate, but the CLI's three-option prompt, its Ctrl+G plan editing, and the automatic session naming on accept have no direct API surface.
  • Version drift is the real hazard here. Behaviour in this area changed at v2.1.205, v2.1.212, v2.1.217, v2.1.228 and v2.1.233. Any guide on this topic without version numbers, including this one a few releases from now, should be checked against claude --version before you trust it.

Written against Claude Code documentation retrieved August 21, 2026. If a behaviour above no longer matches your build, the version notes tell you which direction it moved.

Ren Okabe

Written by

Ren Okabe

Ren builds agent infrastructure and writes copy-paste tutorials for engineers shipping LLM tool-use systems.

Frequently asked questions

How do I get into plan mode in Claude Code?

Press Shift+Tab to cycle to it, prefix a single prompt with /plan, or start the session with claude --permission-mode plan. The status bar reads plan mode on. To make it the default for a project, set {"permissions": {"defaultMode": "plan"}} in .claude/settings.json.

How do I get out of plan mode?

Press Shift+Tab again to leave without approving anything, or approve the plan when Claude presents it. Approving exits plan mode and moves the session into the mode named by the option you chose.

What is the difference between plan mode and edit mode in Claude Code?

Plan mode routes file-edit and shell-write tools to a confirmation step regardless of allow rules, so writes cannot be auto-approved while planning. The acceptEdits mode does the opposite: it auto-approves file edits and common filesystem commands such as mkdir, touch, mv and cp inside the working directory.

Can Claude edit files in plan mode?

Not in a normal session, where edits are blocked until you approve the plan. But in sessions where bypass permissions are available, plan mode's blocks are not enforced and an edit attempted while planning will run. Treat plan mode as a workflow aid rather than a security boundary.

Does Claude run shell commands in plan mode?

Yes, to explore the codebase. When auto mode is available and useAutoModeDuringPlan is on, which is the default, the classifier reviews those commands instead of prompting you. Otherwise anything outside the built-in read-only set prompts for approval.

How do I use plan mode with the Claude Agent SDK?

Pass permission_mode="plan" in Python or permissionMode: "plan" in TypeScript. To switch out mid-session call set_permission_mode() or setPermissionMode(). File edits reach your canUseTool callback rather than being auto-approved.

How does opus plan mode work in Claude Code?

Set the model to opusplan. It uses Opus while you are in plan mode and switches to Sonnet for execution. Use opusplan[1m] to force the 1M context window across both phases.

Do subagents inherit plan mode?

Yes. Subagents inherit the parent session's permission mode, and an AgentDefinition's permissionMode can override it except when the parent is in bypassPermissions, acceptEdits or auto, which always apply to every subagent.

Tutorials

Claude Code Subagents: How to Create, Scope, and Nest Them (2026)

The /agents creation wizard was removed in Claude Code v2.1.198, so almost every guide still ranking for this topic teaches a flow that no longer exists. Here is the current way to write, scope, invoke, and cap Claude Code subagents, with a version number on every claim. August 2026.

15 min read74