bypassPermissions: session startup reads flat pref, GUI toggle writes per-account pref — they never sync

Resolved 💬 2 comments Opened May 28, 2026 by PropellerHead23 Closed Jun 1, 2026

Summary

Claude Desktop has two parallel bypass-permissions gates that are never synchronized. The result: the session startup path silently downgrades bypassPermissions to acceptEdits even when the GUI toggle is enabled.

Gates

| Gate | Pref key | What sets it |
|---|---|---|
| GUI toggle | preferences.bypassPermissionsGateByAccount[accountId] | Clicking the bypass toggle in the Desktop UI |
| Session startup check | preferences.bypassPermissionsModeEnabled (flat boolean) | Not exposed in the UI — defaults to false if missing |

Startup path logic (from .vite/build/index.js)

const f = Bi("bypassPermissionsModeEnabled") === true;  // reads FLAT pref only
const h = d === sn.Bypass && !f;                        // true if bypass requested but flat pref is false
const y = h ? sn.AcceptEdits : d;                      // silently downgrades to AcceptEdits

Bi("bypassPermissionsGateByAccount") is never consulted in this code path. The GUI toggle and the startup-path check are entirely independent.

Symptom

  1. User enables bypass permissions via the Desktop GUI toggle.
  2. New session opens — status bar shows Bypass permissions.
  3. First tool use fires an orange toast: "Bypass Permissions mode isn't enabled."
  4. Mode silently reverts to Accept Edits.

Fix (workaround until app-side fix)

Set the flat pref directly in ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "preferences": {
    "bypassPermissionsModeEnabled": true
  }
}

This must be done while the app is not running (it holds prefs in memory and writes them back on quit, potentially overwriting manual edits).

How this was found

Extracted app.asar with @electron/asar, grepped the bundled JS for the pref name, read the surrounding startup code. Pref names are unobfuscated string literals — greppable directly.

Suggested fix

In the session startup path, check EITHER bypassPermissionsModeEnabled OR bypassPermissionsGateByAccount[accountId] — or better, have the GUI toggle write BOTH prefs atomically so they stay in sync.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗