Skip to content

Fix: Redux Error #9 - Dispatch in reducer - #40

Open
sentry[bot] wants to merge 1 commit into
mainfrom
seer/fix/redux-error-9
Open

Fix: Redux Error #9 - Dispatch in reducer#40
sentry[bot] wants to merge 1 commit into
mainfrom
seer/fix/redux-error-9

Conversation

@sentry

@sentry sentry Bot commented Jul 23, 2026

Copy link
Copy Markdown

This PR resolves the Redux Error #9, which occurred due to a 'dispatch in reducer' violation.

Root Cause:
The setCredentials reducer in src/store/slices/authSlice.ts was directly calling userLogin$.next({}). This synchronous emission, when subscribed to in src/init.ts, could lead to oneSignalActionBasedOnStatus() being called, which in turn might dispatch setShowOneSignalPrompt() while the original setCredentials reducer was still executing. Redux prohibits dispatching actions from within a reducer, leading to Error #9.

Solution:

  1. Removed userLogin$.next({}) from src/store/slices/authSlice.ts: The reducer is now pure and only updates the state.
  2. Introduced Redux listenerMiddleware in src/store/store.ts: A new listener was added that specifically watches for the setCredentials action. Once setCredentials is dispatched and the reducer has completed, the listener asynchronously calls userLogin$.next({}) using setTimeout(0). This ensures that any subsequent dispatches triggered by userLogin$ subscribers happen outside the reducer's execution cycle, preventing the Redux error.

Fixes SH-STUDENT-APP-3

@netlify

netlify Bot commented Jul 23, 2026

Copy link
Copy Markdown

Deploy Preview for studenthub-student failed. Why did it fail? →

Name Link
🔨 Latest commit 00b7684
🔍 Latest deploy log https://app.netlify.com/projects/studenthub-student/deploys/6a61f5e52b824f0008466d7c

Comment thread src/store/store.ts
Comment on lines +13 to +22
listenerMiddleware.startListening({
actionCreator: setCredentials,
effect: () => {
// Emit asynchronously so the reducer has fully completed before any
// subscriber can trigger further dispatches (avoids Redux Error #9).
setTimeout(() => {
userLogin$.next({});
}, 0);
},
});

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Post-login side effects are not triggered when the application reloads with a pre-existing authentication token from localStorage, as no setCredentials action is dispatched.
Severity: MEDIUM

Suggested Fix

Modify the application's initialization sequence. After the store is created with preloadedState, check if an authentication token exists. If it does, manually dispatch an action or trigger the userLogin$ subject to ensure all necessary post-login side effects, like fetching the user profile, are executed.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location: src/store/store.ts#L13-L22

Potential issue: On application load, if an authentication token is present in
`localStorage`, the state is rehydrated with the user already authenticated. However,
the listener middleware is configured to trigger post-login side effects only upon a
`setCredentials` action. Since no such action is dispatched during state rehydration,
critical side effects, such as fetching the user's profile via the `userLogin$` stream,
are not executed. This results in the application operating with potentially stale or
incomplete user data for any user who reloads the page while logged in.

Did we get this right? 👍 / 👎 to inform future reviews.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants