Skip to content

[Bug] prefsStore.onRehydrateStorage callback is dead code — new notification types added to the codebase are never enabled by default for existing users #129

Closed

Description

@cybermax4200

Why this matters now

The notification system is listed as shipped in the current roadmap. mergeNotificationDefaults exists precisely to ensure that when a new notification type (e.g., PROOF_TIMEOUT) is added, existing users who upgrade get that type enabled rather than silently missing notifications. But the onRehydrateStorage callback that calls mergeNotificationDefaults is wired incorrectly for Zustand v4's API and never executes.

Problem / What

src/store/prefsStore.ts:

onRehydrateStorage: () => (persisted, error) => {
  if (error != null || !persisted) { return; }
  const merged = mergeNotificationDefaults(persisted.notificationPrefs);
  usePrefsStore.setState({ notificationPrefs: merged });
},

Zustand v4's persist middleware calls onRehydrateStorage with (state) => void, not with () => (state, error) => void. The outer () => returns a function, but Zustand v4 calls the return value with only state, not (state, error). The inner function is therefore invoked as (persisted) where persisted is the state and error is always undefined — but the outer arrow function is the one actually registered, and its body (return (persisted, error) => {...}) is simply returning a function that Zustand ignores. The setState call never runs.

The fix is to use the Zustand v4 signature directly:

onRehydrateStorage: (state) => {
  if (!state) { return; }
  usePrefsStore.setState({ notificationPrefs: mergeNotificationDefaults(state.notificationPrefs) });
},

Key Challenges

  • The fix is a Zustand API subtlety; the test in prefsStore.test.ts must verify the actual post-rehydration store state, not just that the function was called.
  • Confirm the onRehydrateStorage signature against the installed Zustand version (package.json) to use the correct form.
  • After the fix, run the existing prefsStore.test.ts — it likely passes vacuously because the dead code never ran before.

Acceptance Criteria

  • After rehydration with a stored notificationPrefs that is missing the PROOF_TIMEOUT key, the store contains PROOF_TIMEOUT: true.
  • After rehydration with a stored notificationPrefs that has REWARD_CONFIRMED: false, that preference is preserved (not overwritten by defaults).
  • prefsStore.test.ts has explicit assertions for both cases above.
  • No other onRehydrateStorage side effects are introduced.

Relevant files / functions

  • src/store/prefsStore.ts — onRehydrateStorage, mergeNotificationDefaults
  • src/__tests__/prefsStore.test.ts — extend with rehydration tests

Out of scope

  • Adding new notification types.
  • Changes to quietHours or scheduledNotificationIds persistence.

Activity

  1. chidii commented on Aug 26, 2026

    @chidii
    Contributor

    Hello Maintainer, I've reviewed this issue thoroughly and I'm well positioned to resolve it — experienced across the relevant stack and comfortable navigating the existing codebase. Ready to start right away.

  2. grantfox-oss commented on Aug 26, 2026

    @grantfox-oss

    🦊 GrantFox — @chidii has been assigned to this issue as part of the Third Campaign campaign!

    Next steps:

    1. Open a Pull Request referencing this issue (e.g., Closes #129)
    2. Your PR will be reviewed by the ecotask-network maintainers

    Good luck! Track your progress on GrantFox.

  3. grantfox-oss commented on Aug 30, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox as part of the Third Campaign campaign!

    @chidii's PR #143 was approved and merged by @cybermax4200.

    🏆 @chidii: You earned 40 FoxPoints for this contribution! Your current tier: Builder (1,145 total points). Track your full progress on GrantFox.

    👏 Great work, @chidii! Keep contributing to ecotask-network.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions