Interactive permission mode toggle persists permissions.defaultMode to settings.json
Summary
Toggling the permission mode to "Bypass Permissions" during an interactive session
(via Shift+Tab) writes permissions.defaultMode: "bypassPermissions" into the
user's ~/.claude/settings.json and leaves it there. The next session then
starts in bypass mode by default, which is a dangerous and surprising default
for what was meant to be a session-scoped toggle.
Steps to reproduce
- Start with a clean
~/.claude/settings.jsonthat has nopermissions.defaultModekey. - Launch Claude Code:
claude. - Press
Shift+Tabuntil the permission mode reads "Bypass Permissions". - Exit the session normally (
/exitor Ctrl+D). - Inspect
~/.claude/settings.json.
Expected
The interactive toggle is session-scoped. ~/.claude/settings.json is
unchanged after exit. Re-opening Claude Code starts in the default mode
(or whatever the user explicitly configured).
Actual
~/.claude/settings.json now contains:
{
"permissions": {
"...": "...",
"defaultMode": "bypassPermissions"
}
}
Every subsequent claude invocation starts in bypass-permissions mode
silently, without the user opting in again.
Why this matters
- Bypass mode disables permission prompts for tool use. Persisting it as a
default across all future sessions is a security-sensitive change that the
user did not explicitly request via settings.
- The setting is applied globally (user
settings.json), so it affects every
project, not just the one where the toggle was used.
- There is no in-UI affordance indicating "this toggle will be remembered
forever" — users reasonably expect interactive mode toggles to be ephemeral.
Workaround
I currently mitigate this with a SessionEnd hook that strips the key on
every exit:
{
"hooks": {
"SessionEnd": [
{
"hooks": [
{
"type": "command",
"command": "jq 'del(.permissions.defaultMode)' ~/.claude/settings.json > /tmp/.claude_settings_tmp.json && mv /tmp/.claude_settings_tmp.json ~/.claude/settings.json"
}
]
}
]
}
}
This works but is clearly a workaround for behavior that should not happen
in the first place.
Suggested fix
- Treat interactive
Shift+Tabpermission-mode toggles as session-scoped
only; do not write them to settings.json.
- If persistence is desired, gate it behind an explicit user action
(e.g. a confirmation: "Make this the default for new sessions?") rather
than silently writing on toggle.
- At minimum, never persist
bypassPermissionsas a default without an
explicit, separate confirmation step.
Environment
- Claude Code version: 2.1.138
- OS: macOS (Darwin 25.4.0)
- Settings file affected:
~/.claude/settings.json(global user settings)
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗