anthropics / anthropics/claude-code
[BUG]
- Dominant language
- Python
- Stars
- 145k
- Forks
- 23.1k
- PR merge metrics
- PR metrics pending
Description
### Preflight Checklist
- [x] I have searched [existing issues](https://github.com/anthropics/claude-code/issues?q=is%3Aissue%20state%3Aopen%20label%3Abug) and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
### What's Wrong?
# Plan mode turns itself on mid-session, and its state desyncs from the ExitPlanMode tool
## Summary
Plan mode activates on its own during an active session, without the user requesting it. It happened three times in a single session, including twice **after** the requested work was already finished, committed, pushed, and merged. There is no user message between the preceding tool call and the plan mode notice.
Alongside it, the plan mode state is not consistent between the two places that report it. On the first activation the system reminder said plan mode was active, the agent complied and wrote a plan, and then `ExitPlanMode` rejected the call with "You are not in plan mode." Those two cannot both be true, which is why this looks like a harness state bug rather than an accidental `shift+tab`.
## Environment
- Product: Claude Code
- Surface where this recurs most for me: **Claude Code desktop app**
- Surface where the session below was captured: **Claude Code on the web** (claude.ai/code, remote container)
- Configured model: `claude-opus-5`
- Session: https://claude.ai/code/session_01B6YaiyuoY4foehVBXqtxZK
- Repo: private, Next.js + TypeScript, ~5,400 unit tests
- Task: a small three file frontend change (flip two default values, add a test, update docs), then commit, push, and open a PR
## What happened, in order
1. I asked for a review and fix of a default view setting. No mention of planning.
2. The agent ran ordinary read only investigation: `git status`, `grep`, `sed -n` over two source files.
3. **Plan mode activation #1.** The notice arrived appended to the result of a routine `Bash` read. No user message preceded it. Text: *"Plan mode is active. The user indicated that they do not want you to execute yet ... you MUST NOT make any edits."*
4. The agent followed it: wrote a plan file, asked two clarifying questions, then called `ExitPlanMode`.
5. **`ExitPlanMode` failed** with: *"You are not in plan mode. To enter plan mode, call the EnterPlanMode tool first. If your plan was already approved, continue with implementation."*
This is the core inconsistency. The system reminder asserted plan mode was on; the tool asserted it was off.
6. Work proceeded normally: edits, `tsc --noEmit`, `npm run lint`, full `npm run test`, commit, push, PR opened as draft.
7. **Plan mode activation #2.** The notice arrived appended to the result of `subscribe_pr_activity`, after the PR already existed. Again no user message in between. The plan file was described as already existing, so the harness had retained state from activation #1 even though `ExitPlanMode` had denied that state existed.
8. The agent called `ExitPlanMode` again. This time it returned "User has approved your plan. You can now start coding" **without the user having seen or approved anything**, followed immediately by a second notice reading "You have exited plan mode."
9. Work continued: base branch merged, conflict resolved, revalidated, pushed.
10. **Plan mode activation #3.** The notice arrived appended to a `ReadNotifications` result whose content was that the PR had been **merged**. The task was finished. Plan mode still turned on, instructing the agent not to execute.
11. `ExitPlanMode` was then denied by the user, which is correct behaviour on their part, because from their side it looked like the agent was asking permission to start work that had shipped forty minutes earlier.
12. The user's next message was *"has the plan not been implemented already?"*, which is exactly the confusion this produces.
## Expected vs actual
**Expected:** plan mode turns on when the user asks for it, or when they cycle the permission mode themselves. It stays on until exited. The mode reported in the system reminder matches the mode the `ExitPlanMode` tool sees.
**Actual:** plan mode turns on unprompted, repeatedly, including on a completed task. The reminder and the tool disagree about whether it is on. One `ExitPlanMode` call reported user approval that the user never gave.
## Impact
- **The user is shown an approval prompt for work that is already merged.** That is not just noise, it actively erodes trust in what the agent reports about its own state.
- **Mid task, it stops a run that was going fine.** The agent is told it must not edit, so it stops and writes a plan for something it was already correctly executing.
- **The two disagreeing sources of truth are unresolvable from inside the session.** When the reminder says "you must not edit" and the tool says "you are not in plan mode", there is no call the agent can make to find out which is right. `EnterPlanMode` would be wrong (it would create the state, not read it) and ignoring the reminder risks editing when the user genuinely did ask to plan.
- An `ExitPlanMode` result that says "user has approved" when no human input occurred is the worst version of this, because a model can reasonably read that as consent.
## Frequency
Frequent. Three times in one session here. The reporting user sees it regularly in the desktop app.
## Suspected cause, offered only as a lead
The pattern that every activation rode in on a **tool result** rather than a user turn suggests the plan mode flag is being re-applied when session state is rehydrated or a context window is rolled over, rather than being read from live user intent. That would also explain the desync: the reminder is generated from a stale or restored snapshot while `ExitPlanMode` reads the live value. Activations #2 and #3 both followed points where the session had been idle waiting on external events (a PR subscription, then queued webhook notifications), which is where a rehydration would plausibly occur.
## What would help
1. Plan mode should only be entered from an explicit user action. If something else can set it, the notice should say what set it.
2. The system reminder and `ExitPlanMode` must read the same state. If they can diverge, give the agent a way to query the authoritative value.
3. `ExitPlanMode` should never report "user has approved your plan" unless a human actually approved it. Approval is consent, and synthesising it is dangerous.
4. Do not re-enter plan mode on a session whose in flight work is complete. At minimum, do not re-enter it on rehydration.
5. If the harness has a legitimate reason to enter plan mode by itself, surface that to the user in the transcript, so the approval prompt they get is not context free.
### What Should Happen?
## Expected vs actual
**Expected:** plan mode turns on when the user asks for it, or when they cycle the permission mode themselves. It stays on until exited. The mode reported in the system reminder matches the mode the `ExitPlanMode` tool sees.
**Actual:** plan mode turns on unprompted, repeatedly, including on a completed task. The reminder and the tool disagree about whether it is on. One `ExitPlanMode` call reported user approval that the user never gave.
### Error Messages/Logs
```shell
NA
```
### Steps to Reproduce
## Reproduction
I could not reproduce this deterministically, since it appeared without any action on my part. The full session transcript is the best artifact, and Anthropic can read it from the session link above. The three activation points are identifiable by searching the transcript for the string "Plan mode is active", and the desync is the `ExitPlanMode` call immediately following the first one.
### Claude Model
Opus
### Is this a regression?
Yes, this worked in a previous version
### Last Working Version
_No response_
### Claude Code Version
Desktop App
### Platform
Anthropic API
### Operating System
Windows
### Terminal/Shell
WSL (Windows Subsystem for Linux)
### Additional Information
_No response_
Contributor guide
No contributing guide indexed for this repository
Research direction
No source file or test is identified. Start by reviewing the linked session transcript, especially the three “Plan mode is active” notices and the ExitPlanMode calls after tool results; done means plan mode is entered only by explicit user action and the reminder, tool state, and approval result remain consistent.
Written by the indexing model from the issue text.
Assessment
- Domain
- developer-experience, tooling
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100