react-redux: "Maximum call stack size exceeded" when using v7 with redux saga

Hi! I’m not sure what useful information I can provide to help diagnose this issue, but in my app I’ve just recently upgraded to react-redux@7 and started getting the error in the title. I’ve attached a log from the Chrome developer console and expanded the full stack trace. Note that this only seems to be occurring when NODE_ENV === 'production'. To reiterate: this error does not occur in v6

React: 16.8.6 React-DOM: 16.8.6 Redux: 4.0.1 React-Redux: 7.0.1 Redux-Saga: 1.0.2

Formik: 1.5.2 Firebase: 5.9.2 @sentry/browser: 5.0.5

This issue occurs when saving a Formik form, dispatching an action, which is then handled in Redux-Saga. Redux-Saga creates a saga, converts it to a promise, and then runs the promise as a Cloud Firestore transaction.

Based on the stack trace, it seems like an error is occurring in the new batch method, which is sending the error up and getting caught in a componentDidCatch function at the top of my app. This error is then being reported by Sentry. Here’s a small sample of the code I’m using… sadly, I don’t really have the time at the moment to create a repo that isolates the issue.

Saga code:

import { store } from '../../store/configureStore';
export function* runTransaction(transaction) {
  const firebase = yield select(getFirebaseInstance);

  const response = yield firebase.runTransactionSaga(store, transaction);

  return response;
}

function* updateShowFlow() {
  while (true) {
    const { showId: id, show } = yield take(ShowActions.START_UPDATE_SHOW);
    const firebase = yield select(getFirebaseInstance);

    ...other code and stuff

    yield call(runTransaction, function* t() {
      yield call([firebase.SDK.Shows, 'set'], showId, firebase.SDK.filter(showData, firebase.SDK.Shows.PublicMap));
      yield call([firebase.SDK.Shows.Private(), 'set'], showId, firebase.SDK.filter(showData, firebase.SDK.Shows.PrivateMap));
    });

    ...other code and stuff
  }
}

Firestore code:

this.runTransactionSaga = async (store, callback) => {
      const transactionResponse = await this.client.runTransaction(async (t) => {
        TransactionManager.set(t);

        return runSaga(store, callback).toPromise();
      });

      TransactionManager.unset();

      return transactionResponse;
    };

And the stack trace from the chrome console logger

breadcrumbs.js:81 RangeError: Maximum call stack size exceeded
    at isUndefinedOrNull (index.js:29)
    at objEquiv (index.js:46)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
    at f66B.module.exports (index.js:25)
    at objEquiv (index.js:98)
(anonymous) @ breadcrumbs.js:81
qh @ react-dom.production.min.js:4410
Eh.f.componentDidCatch.c.callback @ react-dom.production.min.js:4799
ih @ react-dom.production.min.js:4273
hh @ react-dom.production.min.js:4261
Vh @ react-dom.production.min.js:4985
Zh @ react-dom.production.min.js:5125
(anonymous) @ react-dom.production.min.js:5977
+wdc.exports.unstable_runWithPriority @ scheduler.production.min.js:276
Fi @ react-dom.production.min.js:5976
Di @ react-dom.production.min.js:5960
Yh @ react-dom.production.min.js:5927
Gi @ react-dom.production.min.js:5994
notify @ Subscription.js:23
notifyNestedSubs @ Subscription.js:65
notifySubscribers @ Provider.js:59
handleChangeWrapper @ Subscription.js:70
dispatch @ redux.js:216
(anonymous) @ redux-saga-core.esm.js:1421
(anonymous) @ middleware.js:36
dispatch @ redux.js:615
(anonymous) @ chunk-e922c950.js:136
(anonymous) @ redux-saga-core.esm.js:484
exec @ redux-saga-core.esm.js:30
flush @ redux-saga-core.esm.js:88
asap @ redux-saga-core.esm.js:45
runPutEffect @ redux-saga-core.esm.js:480
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
end @ redux-saga-core.esm.js:1020
task.cont @ redux-saga-core.esm.js:845
next @ redux-saga-core.esm.js:1176
currCb @ redux-saga-core.esm.js:1257
Promise.then (async)
resolvePromise @ redux-saga-core.esm.js:407
runEffect @ redux-saga-core.esm.js:1202
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
runSelectEffect @ redux-saga-core.esm.js:741
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
proc @ redux-saga-core.esm.js:1114
runCallEffect @ redux-saga-core.esm.js:544
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
checkEnd @ chunk-e922c950.js:172
chCbAtKey @ chunk-e922c950.js:188
currCb @ redux-saga-core.esm.js:1257
Promise.then (async)
resolvePromise @ redux-saga-core.esm.js:407
runCallEffect @ redux-saga-core.esm.js:538
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
(anonymous) @ redux-saga-core.esm.js:683
runAllEffect @ redux-saga-core.esm.js:682
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
(anonymous) @ redux-saga-core.esm.js:493
exec @ redux-saga-core.esm.js:30
flush @ redux-saga-core.esm.js:88
asap @ redux-saga-core.esm.js:45
chan.put @ redux-saga-core.esm.js:387
(anonymous) @ redux-saga-core.esm.js:1423
(anonymous) @ middleware.js:36
(anonymous) @ redux.js:465
onSubmit @ Edit.jsx:216
Formik._this.executeSubmit @ formik.esm.js:462
(anonymous) @ formik.esm.js:452
Promise.then (async)
Formik._this.submitForm @ formik.esm.js:442
Formik._this.handleSubmit @ formik.esm.js:429
ca @ react-dom.production.min.js:51
ja @ react-dom.production.min.js:71
ka @ react-dom.production.min.js:75
wa @ react-dom.production.min.js:142
Aa @ react-dom.production.min.js:171
ya @ react-dom.production.min.js:160
Da @ react-dom.production.min.js:234
Ad @ react-dom.production.min.js:1720
Gi @ react-dom.production.min.js:5992
Kb @ react-dom.production.min.js:662
Dd @ react-dom.production.min.js:1762
(anonymous) @ react-dom.production.min.js:6019
+wdc.exports.unstable_runWithPriority @ scheduler.production.min.js:276
Ii @ react-dom.production.min.js:6018
Cd @ react-dom.production.min.js:1739
sentryWrapped @ helpers.js:84
Show 5 more frames
VM80:1 Fetch finished loading: POST "https://sentry.io/api/1414499/store/?sentry_key=adbc85609ec74fa9ba7b1726cbe6f1f7&sentry_version=7".
(anonymous) @ VM80:1
(anonymous) @ fetch.js:37
step @ tslib.es6.js:210
(anonymous) @ tslib.es6.js:140
(anonymous) @ tslib.es6.js:113
__awaiter @ tslib.es6.js:90
FetchTransport.sendEvent @ fetch.js:23
BaseBackend.sendEvent @ basebackend.js:52
(anonymous) @ baseclient.js:402
onSuccess @ syncpromise.js:135
(anonymous) @ syncpromise.js:83
SyncPromise._executeHandlers @ syncpromise.js:82
SyncPromise._attachHandler @ syncpromise.js:96
(anonymous) @ syncpromise.js:113
SyncPromise @ syncpromise.js:100
SyncPromise.then @ syncpromise.js:112
(anonymous) @ baseclient.js:390
SyncPromise @ syncpromise.js:100
BaseClient._processEvent @ baseclient.js:389
(anonymous) @ baseclient.js:75
onSuccess @ syncpromise.js:135
(anonymous) @ syncpromise.js:83
SyncPromise._executeHandlers @ syncpromise.js:82
SyncPromise._attachHandler @ syncpromise.js:96
(anonymous) @ syncpromise.js:113
SyncPromise @ syncpromise.js:100
SyncPromise.then @ syncpromise.js:112
BaseClient.captureException @ baseclient.js:74
Hub._invokeClient @ hub.js:81
Hub.captureException @ hub.js:173
callOnHub @ index.js:20
captureException @ index.js:42
(anonymous) @ App.jsx:262
Hub.withScope @ hub.js:134
callOnHub @ index.js:20
withScope @ index.js:114
componentDidCatch @ App.jsx:258
Eh.f.componentDidCatch.c.callback @ react-dom.production.min.js:4800
ih @ react-dom.production.min.js:4273
hh @ react-dom.production.min.js:4261
Vh @ react-dom.production.min.js:4985
Zh @ react-dom.production.min.js:5125
(anonymous) @ react-dom.production.min.js:5977
+wdc.exports.unstable_runWithPriority @ scheduler.production.min.js:276
Fi @ react-dom.production.min.js:5976
Di @ react-dom.production.min.js:5960
Yh @ react-dom.production.min.js:5927
Gi @ react-dom.production.min.js:5994
notify @ Subscription.js:23
notifyNestedSubs @ Subscription.js:65
notifySubscribers @ Provider.js:59
handleChangeWrapper @ Subscription.js:70
dispatch @ redux.js:216
(anonymous) @ redux-saga-core.esm.js:1421
(anonymous) @ middleware.js:36
dispatch @ redux.js:615
(anonymous) @ chunk-e922c950.js:136
(anonymous) @ redux-saga-core.esm.js:484
exec @ redux-saga-core.esm.js:30
flush @ redux-saga-core.esm.js:88
asap @ redux-saga-core.esm.js:45
runPutEffect @ redux-saga-core.esm.js:480
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
end @ redux-saga-core.esm.js:1020
task.cont @ redux-saga-core.esm.js:845
next @ redux-saga-core.esm.js:1176
currCb @ redux-saga-core.esm.js:1257
Promise.then (async)
resolvePromise @ redux-saga-core.esm.js:407
runEffect @ redux-saga-core.esm.js:1202
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
runSelectEffect @ redux-saga-core.esm.js:741
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
proc @ redux-saga-core.esm.js:1114
runCallEffect @ redux-saga-core.esm.js:544
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
checkEnd @ chunk-e922c950.js:172
chCbAtKey @ chunk-e922c950.js:188
currCb @ redux-saga-core.esm.js:1257
Promise.then (async)
resolvePromise @ redux-saga-core.esm.js:407
runCallEffect @ redux-saga-core.esm.js:538
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
(anonymous) @ redux-saga-core.esm.js:683
runAllEffect @ redux-saga-core.esm.js:682
runEffect @ redux-saga-core.esm.js:1210
digestEffect @ redux-saga-core.esm.js:1277
next @ redux-saga-core.esm.js:1167
currCb @ redux-saga-core.esm.js:1257
(anonymous) @ redux-saga-core.esm.js:493
exec @ redux-saga-core.esm.js:30
flush @ redux-saga-core.esm.js:88
asap @ redux-saga-core.esm.js:45
chan.put @ redux-saga-core.esm.js:387
(anonymous) @ redux-saga-core.esm.js:1423
(anonymous) @ middleware.js:36
(anonymous) @ redux.js:465
onSubmit @ Edit.jsx:216
Formik._this.executeSubmit @ formik.esm.js:462
(anonymous) @ formik.esm.js:452
Promise.then (async)
Formik._this.submitForm @ formik.esm.js:442
Formik._this.handleSubmit @ formik.esm.js:429
ca @ react-dom.production.min.js:51
ja @ react-dom.production.min.js:71
ka @ react-dom.production.min.js:75
wa @ react-dom.production.min.js:142
Aa @ react-dom.production.min.js:171
ya @ react-dom.production.min.js:160
Da @ react-dom.production.min.js:234
Ad @ react-dom.production.min.js:1720
Gi @ react-dom.production.min.js:5992
Kb @ react-dom.production.min.js:662
Dd @ react-dom.production.min.js:1762
(anonymous) @ react-dom.production.min.js:6019
+wdc.exports.unstable_runWithPriority @ scheduler.production.min.js:276
Ii @ react-dom.production.min.js:6018
Cd @ react-dom.production.min.js:1739
sentryWrapped @ helpers.js:84
Show 40 more frames

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 5
  • Comments: 15 (5 by maintainers)

Most upvoted comments

I had the same issue. Only happens in production. Updating react-helmet npm install --save react-helmet@6.0.0-beta helps (https://github.com/nfl/react-helmet/issues/437#issuecomment-488805904)! Even though react-helmet wasn’t mentioned in any way in the error stack.

Based on some googling, it looks like something else in your stack is doing a deepEqual on the resulting component. It came up with older versions of react-helmet, but others might be using it too.

We now use React.memo on the wrapped component, which returns an object back. That has a very deeply nested structure, so deepEqual is recursing too far into the object tree. I don’t think there’s anything for us to do here.

One thing to try is setting pure: false on the connect options and see if that fixes it. If so, then it’s definitely the issue I mentioned above. There still isn’t anything for us to do about that, since we’re returning a valid React component. But that would at least explain it and something for you to get a fix for from the library creating the error.

I’m having the same issue but I’m not using redux-saga. I wanted to upgrade from react-redux v6 to v7. Note that in only happens with a production build, not in dev mode.

Here is the error:

react-dom.production.min.js:4408 RangeError: Maximum call stack size exceeded
    at Function.[Symbol.hasInstance] (<anonymous>)
    at t.exports (index.js:12)
    at index.js:96
    at t.exports (index.js:23)
    at index.js:96
    at t.exports (index.js:23)
    at index.js:96
    at t.exports (index.js:23)
    at index.js:96
    at t.exports (index.js:23)
function location
Ea.n.callback react-dom.production.min.js:4773
ia react-dom.production.min.js:4271
ra react-dom.production.min.js:4259
qa react-dom.production.min.js:4999
Wa react-dom.production.min.js:5123
(anonymous) react-dom.production.min.js:5975
e.unstable_runWithPriority scheduler.production.min.js:274
Ps react-dom.production.min.js:5974
ks react-dom.production.min.js:5958
Is react-dom.production.min.js:5925
Ns react-dom.production.min.js:5992
notify Subscription.js:23
e.notifyNestedSubs Subscription.js:65
n.notifySubscribers Provider.js:59
e.handleChangeWrapper Subscription.js:70
m redux.js:213
(anonymous) index.js:11
dispatch redux.js:613
(anonymous) listen.js:24
next index.cjs.js:25242
(anonymous) index.cjs.js:22823
setTimeout (async)
t.scheduleEvent index.cjs.js:22821
t.next index.cjs.js:22806
t.raiseInitialEvent index.cjs.js:19381
t.onViewSnapshot index.cjs.js:19314
t.onWatchChange index.cjs.js:19233
(anonymous) index.cjs.js:20686
(anonymous) tslib.es6.js:208
(anonymous) tslib.es6.js:138
a tslib.es6.js:91
Promise.then (async)
u tslib.es6.js:108
(anonymous) tslib.es6.js:111
l tslib.es6.js:88
t.emitNewSnapsAndNotifyLocalStore index.cjs.js:20635
(anonymous) index.cjs.js:20314
Promise.then (async)
t.applyRemoteEvent index.cjs.js:20294
t.raiseWatchSnapshot index.cjs.js:18755
(anonymous) index.cjs.js:18684
(anonymous) tslib.es6.js:208
(anonymous) tslib.es6.js:138
a tslib.es6.js:91
Promise.then (async)
u tslib.es6.js:108
(anonymous) tslib.es6.js:111
l tslib.es6.js:88
t.onWatchStreamChange index.cjs.js:18643
e.onMessage index.cjs.js:17590
(anonymous) index.cjs.js:17499
(anonymous) index.cjs.js:17549
(anonymous) index.cjs.js:8968
Promise.then (async)
t.enqueue index.cjs.js:8966
t.enqueueAndForget index.cjs.js:8954
(anonymous) index.cjs.js:17547
(anonymous) index.cjs.js:17498
t.callOnMessage index.cjs.js:8264
(anonymous) index.cjs.js:8545
(anonymous) index.cjs.js:8488
r.ua index.esm.js:697
r.dispatchEvent index.esm.js:652
ze.ob index.esm.js:2916
r.Ad index.esm.js:2689
r.bc index.esm.js:2595
r.Wa index.esm.js:1265
r.vb index.esm.js:1167
r.Ed index.esm.js:1132
r.oc index.esm.js:1115
r.Hd index.esm.js:1110
r.ua index.esm.js:697
r.dispatchEvent index.esm.js:652
r.$b index.esm.js:2160
r.Bd index.esm.js:2156
r.ac index.esm.js:2152
XMLHttpRequest.send (async)
r.xa index.esm.js:2107
r.ic index.esm.js:1103
r.bb index.esm.js:1090
r.Vd index.esm.js:2570
r.cc index.esm.js:2554
Dt index.esm.js:797
Promise.then (async)
Ct index.esm.js:787
r.zb index.esm.js:2538
r.Wd index.esm.js:2697
r.Ad index.esm.js:2687
r.bc index.esm.js:2595
r.Wa index.esm.js:1265
r.vb index.esm.js:1167
r.Ed index.esm.js:1132
r.oc index.esm.js:1115
r.Hd index.esm.js:1110
r.ua index.esm.js:697
r.dispatchEvent index.esm.js:652
r.$b index.esm.js:2160
r.Bd index.esm.js:2156
r.ac index.esm.js:2152
XMLHttpRequest.send (async)
r.xa index.esm.js:2107
r.ic index.esm.js:1103
r.cb index.esm.js:1082
r.Fd index.esm.js:2494
r.Xd index.esm.js:2476
r.dc index.esm.js:2472
(anonymous) index.esm.js:964
setTimeout (async)
Gt index.esm.js:963
r.Ma index.esm.js:2458
r.Cc index.esm.js:2400
r.na index.esm.js:2578
r.rb index.esm.js:1789
r.Vc index.esm.js:1784
r.Dc index.esm.js:2395
r.bd index.esm.js:2371
r.Yc index.esm.js:2855
sendFn index.cjs.js:8465
t.send index.cjs.js:8249
t.sendRequest index.cjs.js:17344
e.watch index.cjs.js:17610
t.sendWatchRequest index.cjs.js:18561
(anonymous) index.cjs.js:18605
C index.cjs.js:514
(anonymous) index.cjs.js:18604
(anonymous) tslib.es6.js:208
(anonymous) tslib.es6.js:138
(anonymous) tslib.es6.js:111
l tslib.es6.js:88
t.onWatchStreamOpen index.cjs.js:18600
(anonymous) index.cjs.js:17489
(anonymous) index.cjs.js:17549
(anonymous) index.cjs.js:8968
Promise.then (async)
t.enqueue index.cjs.js:8966
t.enqueueAndForget index.cjs.js:8954
(anonymous) index.cjs.js:17547
(anonymous) index.cjs.js:17486
t.callOnOpen index.cjs.js:8254
(anonymous) index.cjs.js:8554
setTimeout (async)
t.openStream index.cjs.js:8549
e.startRpc index.cjs.js:17582
t.startStream index.cjs.js:17484
(anonymous) index.cjs.js:17469
Promise.then (async)
t.auth index.cjs.js:17460
t.start index.cjs.js:17266
t.startWatchStream index.cjs.js:18578
t.listen index.cjs.js:18514
(anonymous) index.cjs.js:20059
(anonymous) tslib.es6.js:208
(anonymous) tslib.es6.js:138
a tslib.es6.js:91
Promise.then (async)
u tslib.es6.js:108
a tslib.es6.js:91
Promise.then (async)
u tslib.es6.js:108
(anonymous) tslib.es6.js:111
l tslib.es6.js:88
t.listen index.cjs.js:20019
t.listen index.cjs.js:19184
(anonymous) index.cjs.js:22691
(anonymous) index.cjs.js:8968
Promise.then (async)
t.enqueue index.cjs.js:8966
t.enqueueAndForget index.cjs.js:8954
t.listen index.cjs.js:22690
t.onSnapshotInternal index.cjs.js:25248
t.onSnapshot index.cjs.js:25225
(anonymous) listen.js:23
(anonymous) index.js:8
601 index.js:34
f (index):1
278 main.0411db18.chunk.js:1
f (index):1
a (index):1
e (index):1
(anonymous) main.0411db18.chunk.js:1

Here is my package.json dependencies:

{
  "firebase": "^5.9.4",
  "jump.js": "^1.0.2",
  "react": "^16.8.6",
  "react-app-polyfill": "^0.2.2",
  "react-dom": "^16.8.6",
  "react-helmet": "^5.2.0",
  "react-icons": "^3.5.0",
  "react-markdown": "^4.0.6",
  "react-redux": "^7.0.1",
  "react-router-dom": "^5.0.0",
  "react-scripts": "^2.1.8",
  "redux": "^4.0.1",
  "redux-form": "^8.2.0",
  "redux-logger": "^3.0.6",
  "redux-thunk": "^2.3.0"
}