Summary
The preferences "move volume from general to sound" migration is a no-op on exactly the data it targets, and separately clobbers a deliberately-muted volume: 0.
Details
src/stores/preferencesStore.ts:149-154:
if (parsed.general?.volume !== undefined && parsed.sound) {
if (!parsed.sound.volume) {
parsed.sound.volume = parsed.general.volume;
}
delete parsed.general.volume;
}
Two problems:
-
The data this migration exists to fix was written before sound existed, so it has no parsed.sound key. The && parsed.sound guard makes the whole block a no-op on precisely that data. The saved volume is lost (falls back to the default 1.0 at line 102), and the stale general.volume survives via the {...initial.general, ...stored.general} merge (line 121) and is re-persisted every save.
-
if (!parsed.sound.volume) treats a deliberate 0 (muted) as "absent" and overwrites it.
There is no schema-version field in the persisted shape, so migrated and unmigrated data are indistinguishable.
Fix direction
Migrate when general.volume is present regardless of whether sound exists (create it), and use sound.volume === undefined rather than falsiness so 0 is preserved. Consider adding a version field to the persisted blob.
Verification
Read src/stores/preferencesStore.ts end to end.
Summary
The preferences "move volume from general to sound" migration is a no-op on exactly the data it targets, and separately clobbers a deliberately-muted
volume: 0.Details
src/stores/preferencesStore.ts:149-154:Two problems:
The data this migration exists to fix was written before
soundexisted, so it has noparsed.soundkey. The&& parsed.soundguard makes the whole block a no-op on precisely that data. The saved volume is lost (falls back to the default1.0at line 102), and the stalegeneral.volumesurvives via the{...initial.general, ...stored.general}merge (line 121) and is re-persisted every save.if (!parsed.sound.volume)treats a deliberate0(muted) as "absent" and overwrites it.There is no schema-version field in the persisted shape, so migrated and unmigrated data are indistinguishable.
Fix direction
Migrate when
general.volumeis present regardless of whethersoundexists (create it), and usesound.volume === undefinedrather than falsiness so0is preserved. Consider adding a version field to the persisted blob.Verification
Read
src/stores/preferencesStore.tsend to end.