Bug: Settings > Vault Enabled switch flips visually but doesn't enable vault #162

Closed
opened 2026-09-08 19:33:05 +00:00 by Mark · 0 comments
Owner

Bug

On the Settings page, toggling the Vault Enabled Radix switch shows it visually flipping to "checked" (aria-checked=true, data-state="checked"), but the conditional vault sub-rows (Auto-lock Delay, Change PIN, Lock Vault Now, Reset Vault Data, Quick-Hide) do not render, and navigating to #/vault shows "Vault Disabled - Enable the vault in Settings to protect sensitive contacts" even though the Settings switch reads as ON.

Repro

  1. Start dev server, navigate to #/settings
  2. Scroll to the Vault section
  3. Click the Vault Enabled switch (use Radix pointer sequence: pointerdown + pointerup + click)
  4. Observe: switch now shows aria-checked="true", data-state="checked"
  5. Observe: sub-rows Auto-lock Delay / Change PIN / Lock Vault Now / Reset Vault Data / Quick-Hide do NOT appear below
  6. Navigate to #/vault
  7. Observe: page shows "Vault Disabled - Enable the vault in Settings"
  8. Navigate back to #/settings - switch is still shown as checked, sub-rows still missing

What's known

  • Both the <Switch checked={vaultSettings.vaultEnabled}> and the conditional {vaultSettings.vaultEnabled && (...)} read the same vaultSettings from useStore(useShallow((s) => s.vaultSettings)) (Settings.tsx:163)
  • The store action setVaultEnabled (store.ts:1219-1223) does both set({ vaultSettings: newSettings }) and batchPrefSet("vaultSettings", ...)
  • The Switch DOES flip its controlled prop visually (Radix accepts the toggle), but the conditional that owns the sub-rows doesn't re-render
  • This is not a general Radix-Switch bug: the "Invest in this relationship" Radix switch on PersonDetail.tsx toggles and persists correctly across navigation

Suggested investigation paths

  • Controlled/uncontrolled mismatch in src/components/ui/switch.tsx - the wrapper spreads ...props onto SwitchRoot; verify Radix's checked/onCheckedChange pair is being honored
  • useShallow on vaultSettings returning the wrong reference somehow - instrument with a console.log inside setVaultEnabled to confirm set({ vaultSettings: newSettings }) runs
  • batchPrefSet's async round-trip via Preferences.set reverting in-memory state before React commits - possible if a hydration step re-reads preferences from Capacitor

Severity

Functional. The whole Vault feature is unreachable from Settings because the enable-toggle doesn't actually enable it.

Source pointers

  • src/pages/Settings.tsx:1043-1053 (Switch binding)
  • src/pages/Settings.tsx:1055 (conditional that doesn't render)
  • src/lib/store.ts:1219-1223 (setVaultEnabled action)
  • src/pages/Vault.tsx:120 (vaultDisabled = !vaultSettings.vaultEnabled)
  • src/components/ui/switch.tsx (Switch wrapper)
## Bug On the Settings page, toggling the **Vault Enabled** Radix switch shows it visually flipping to "checked" (aria-checked=true, data-state="checked"), but the conditional vault sub-rows (Auto-lock Delay, Change PIN, Lock Vault Now, Reset Vault Data, Quick-Hide) **do not render**, and navigating to `#/vault` shows **"Vault Disabled - Enable the vault in Settings to protect sensitive contacts"** even though the Settings switch reads as ON. ## Repro 1. Start dev server, navigate to `#/settings` 2. Scroll to the **Vault** section 3. Click the **Vault Enabled** switch (use Radix pointer sequence: `pointerdown` + `pointerup` + `click`) 4. Observe: switch now shows `aria-checked="true"`, `data-state="checked"` 5. Observe: sub-rows **Auto-lock Delay / Change PIN / Lock Vault Now / Reset Vault Data / Quick-Hide** do NOT appear below 6. Navigate to `#/vault` 7. Observe: page shows **"Vault Disabled - Enable the vault in Settings"** 8. Navigate back to `#/settings` - switch is still shown as checked, sub-rows still missing ## What's known - Both the `<Switch checked={vaultSettings.vaultEnabled}>` and the conditional `{vaultSettings.vaultEnabled && (...)}` read the same `vaultSettings` from `useStore(useShallow((s) => s.vaultSettings))` (Settings.tsx:163) - The store action `setVaultEnabled` (store.ts:1219-1223) does both `set({ vaultSettings: newSettings })` and `batchPrefSet("vaultSettings", ...)` - The Switch DOES flip its controlled prop visually (Radix accepts the toggle), but the conditional that owns the sub-rows doesn't re-render - This is **not** a general Radix-Switch bug: the "Invest in this relationship" Radix switch on `PersonDetail.tsx` toggles and persists correctly across navigation ## Suggested investigation paths - Controlled/uncontrolled mismatch in `src/components/ui/switch.tsx` - the wrapper spreads `...props` onto SwitchRoot; verify Radix's `checked`/`onCheckedChange` pair is being honored - `useShallow` on `vaultSettings` returning the wrong reference somehow - instrument with a console.log inside `setVaultEnabled` to confirm `set({ vaultSettings: newSettings })` runs - `batchPrefSet`'s async round-trip via `Preferences.set` reverting in-memory state before React commits - possible if a hydration step re-reads preferences from Capacitor ## Severity Functional. The whole Vault feature is unreachable from Settings because the enable-toggle doesn't actually enable it. ## Source pointers - `src/pages/Settings.tsx:1043-1053` (Switch binding) - `src/pages/Settings.tsx:1055` (conditional that doesn't render) - `src/lib/store.ts:1219-1223` (setVaultEnabled action) - `src/pages/Vault.tsx:120` (`vaultDisabled = !vaultSettings.vaultEnabled`) - `src/components/ui/switch.tsx` (Switch wrapper)
Mark 2026-09-08 19:53:10 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Mark/kimi_agent_kin_app_sync#162
No description provided.