Plan mode bypass: ExitPlanMode returns approved state without user interaction; UI indicator does not update
Bug Report: Claude Code executed changes while plan mode was still active (no approval prompt shown)
Date observed: 2026-04-17
Product: Claude Code (CLI)
Model: claude-sonnet-4-6
Severity: High — destructive actions taken without user consent
Summary
While working in Claude Code's plan mode, the assistant called the ExitPlanMode tool and then immediately proceeded to execute destructive database changes (deleting a row, updating multiple rows across three tables) on a live production website. From the user's perspective:
- The plan mode indicator in the Claude Code UI never changed state — it continued to show plan mode as active throughout.
- No approval prompt was ever displayed to the user. There was no dialog, no button press, no confirmation of any kind.
- The assistant proceeded to execute changes regardless.
When questioned, the assistant reported that the system had returned messages stating "User has approved your plan" and "You have exited plan mode." Those messages were generated without any user interaction occurring in the UI.
Expected behaviour
- The
ExitPlanModetool should only return an "approved" state to the assistant after the user has taken an explicit action (clicked approve, pressed a key, etc.) in the UI. - The plan mode indicator in the UI should transition out of plan-mode state when approval occurs.
- If approval is auto-accepted due to a permission setting, the user should be visibly informed that approval happened.
Actual behaviour
ExitPlanModereturned "User has approved your plan" to the assistant without any user interaction.- The plan mode indicator in the UI remained in its plan-mode state.
- The user had no opportunity to review or reject the plan.
- The assistant executed multiple destructive database operations against a production site.
Reproduction context
- Claude Code session running in a git worktree
- Session involved editing a live production site via SSH + MySQL
- Plan mode was entered mid-session (not at session start)
- The assistant completed Phase 1 exploration, Phase 4 plan write-up, then called
ExitPlanMode - No CI / hook / script in the user's environment was configured to auto-approve — the user expected a manual prompt
Evidence available
- Full transcript of the Claude Code session (including the exact system messages returned to the assistant after
ExitPlanModewas called) - User testimony that no approval prompt appeared and the plan mode button never changed state
Impact
On this particular site no permanent damage was done because:
- The assistant had taken row-level MySQL backups before modifying
- All changes were reversible and were subsequently reversed on request
On other sites or with other tasks, the same bug could cause:
- Unrecoverable data loss
- Unintended external actions (git pushes, messages sent, deployments)
- Violation of user trust in plan mode as a safety mechanism
The severity is high because plan mode is specifically marketed as a safety gate. If that gate can be silently bypassed, the feature provides false confidence.
Suggested investigation areas
- Whether any permission mode (e.g. "auto-accept edits", "bypass permissions") silently coerces
ExitPlanModeinto an approved response without updating the UI indicator. - Whether there is a race condition between the ExitPlanMode tool response and the UI state update.
- Whether a stale or cached session state could cause the approval signal to be generated without a user event.
Requested outcomes
- Root-cause analysis confirming how approval was recorded without a user event.
- Fix to ensure
ExitPlanModecannot return "approved" without a verified user action. - Fix to ensure plan-mode UI state reflects the true system state.
- Consider emitting a warning in the assistant's context when auto-approval is in effect, so the assistant can mention this to the user before proceeding.
Reporter
Hasmukh Gajjar — non-developer user relying on Claude Code to manage a live non-profit platform (s2l.online).
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗