seasonalThemeOverride is the only enum setting with no persisted-value validation #74

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

Severity: low · Type: tech-debt · Confidence: medium

Location: src/app/state/settings.ts:379-430 (getSettings)

Problem

Every other enum-like setting that can drift across releases (callNoiseSuppression, callDenoiseModel, ringtoneId, translateTargetLang) is explicitly whitelisted/coerced back to a safe default inside getSettings(). seasonalThemeOverride is not: {...defaultSettings, ...saved} passes through whatever string was persisted verbatim. Since resolveSeasonTheme (seasonSchedule.ts:106-110) returns any non-'auto'/'off' override value as-is, and buildOverlayContent's switch falls through to default: return null for anything unrecognized, a persisted theme id that's ever renamed or removed from the union would silently render nothing, while SEASONAL_OPTIONS in the settings UI would no longer have a matching entry to show as selected — a UI/stored-state disagreement with no obvious explanation to the user.

How to trigger

Not currently reproducible against the present code (all persisted values are still valid) — would only manifest after a future release renames/drops a theme id while a user has it pinned. Reported as tech-debt/latent risk, not an active bug.

Suggested fix

Add the same kind of whitelist coercion used for ringtoneId/callDenoiseModel, falling back to 'auto' for any value outside the current seasonalThemeOverride union.


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

**Severity:** low · **Type:** tech-debt · **Confidence:** medium **Location:** `src/app/state/settings.ts:379-430` (`getSettings`) ### Problem Every other enum-like setting that can drift across releases (`callNoiseSuppression`, `callDenoiseModel`, `ringtoneId`, `translateTargetLang`) is explicitly whitelisted/coerced back to a safe default inside `getSettings()`. `seasonalThemeOverride` is not: `{...defaultSettings, ...saved}` passes through whatever string was persisted verbatim. Since `resolveSeasonTheme` (`seasonSchedule.ts:106-110`) returns any non-`'auto'`/`'off'` override value as-is, and `buildOverlayContent`'s `switch` falls through to `default: return null` for anything unrecognized, a persisted theme id that's ever renamed or removed from the union would silently render nothing, while `SEASONAL_OPTIONS` in the settings UI would no longer have a matching entry to show as selected — a UI/stored-state disagreement with no obvious explanation to the user. ### How to trigger Not currently reproducible against the present code (all persisted values are still valid) — would only manifest after a future release renames/drops a theme id while a user has it pinned. Reported as tech-debt/latent risk, not an active bug. ### Suggested fix Add the same kind of whitelist coercion used for `ringtoneId`/`callDenoiseModel`, falling back to `'auto'` for any value outside the current `seasonalThemeOverride` union. --- _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:27 -04:00
jared added the priority: lowtech-debtarea: settings labels 2026-09-12 01:51:27 -04:00
jared self-assigned this 2026-09-12 01:51:27 -04:00
jared closed this issue 2026-09-12 20:29:03 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: LotusGuild/cinny#74