Settings are never synced across tabs — one tab's whole blob clobbers the other's #42

Closed
opened 2026-09-12 01:51:09 -04:00 by jared · 0 comments
Owner

Severity: medium · Type: bug · Confidence: high

Location: src/app/state/settings.ts:379-455

Problem

getSettings() is called exactly once at module load (const baseSettings = atom<Settings>(getSettings())) and setSettings serializes the entire settings object on every change. Unlike atomWithLocalStorage (src/app/state/utils/atomWithLocalStorage.ts:30-39), which does install a storage listener, the main settings atom has none. Two open tabs therefore each hold a snapshot from their own load time; whichever writes last silently reverts every setting the other tab changed since. This affects the largest settings surface in the app (theme, notifications, call/denoise, composer toolbar, translation).

How to trigger

open the app in two tabs. In tab A change the theme. In tab B toggle any unrelated setting. Reload tab A — the theme change is gone.

Suggested fix

give settingsAtom an onMount storage listener keyed on 'settings' that re-reads via getSettings() (mirroring atomWithLocalStorage), or merge-on-write by re-reading the stored blob before setItem.


Filed from the September 2026 client audit (branch lotus @ 4bea4895).

**Severity:** medium · **Type:** bug · **Confidence:** high **Location:** `src/app/state/settings.ts:379-455` ### Problem `getSettings()` is called exactly once at module load (`const baseSettings = atom<Settings>(getSettings())`) and `setSettings` serializes the **entire** settings object on every change. Unlike `atomWithLocalStorage` (`src/app/state/utils/atomWithLocalStorage.ts:30-39`), which does install a `storage` listener, the main settings atom has none. Two open tabs therefore each hold a snapshot from their own load time; whichever writes last silently reverts every setting the other tab changed since. This affects the largest settings surface in the app (theme, notifications, call/denoise, composer toolbar, translation). ### How to trigger open the app in two tabs. In tab A change the theme. In tab B toggle any unrelated setting. Reload tab A — the theme change is gone. ### Suggested fix give `settingsAtom` an `onMount` `storage` listener keyed on `'settings'` that re-reads via `getSettings()` (mirroring `atomWithLocalStorage`), or merge-on-write by re-reading the stored blob before `setItem`. --- _Filed from the September 2026 client audit (branch `lotus` @ 4bea4895)._
jared added this to the Audit 2026-09 · Medium & Low milestone 2026-09-12 01:51:09 -04:00
jared added the bugpriority: mediumarea: settings labels 2026-09-12 01:51:09 -04:00
jared self-assigned this 2026-09-12 01:51:09 -04:00
jared closed this issue 2026-09-15 21:32:09 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
2026-11-14
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#42