Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: performUpdateIfNecessary: Unexpected batch number ... #6895

Closed
brotzky opened this issue May 26, 2016 · 55 comments
Closed

Error: performUpdateIfNecessary: Unexpected batch number ... #6895

brotzky opened this issue May 26, 2016 · 55 comments
Assignees

Comments

@brotzky
Copy link

brotzky commented May 26, 2016

From maintainers: if you have this problem, please see the explanation in #6895 (comment).

I am getting a strange error I've never come across. Googling it doesn't help at all.
Error: performUpdateIfNecessary: Unexcpeted batch number (current 36, pending 31)(...)
It has caused me a lot of headaches. I've reverted to 2 days ago and the error persists, even though 2 days ago everything was running smoothly and all tests were passing.

I would appreciate any sort of direction as to how I can begin to resolve this bug. My guesses are that it's an error with Redux, Webpack, Redux-Form, or React itself. I know, not that precise, but I'm quite lost.


Example redux logger information:
screen shot 2016-05-26 at 11 18 43 am

Max OS X, El Capitan 10.11.5
React v15.0.1 (error persists on v15.1.0)

I'm sorry if this isn't specific to React. I did look into the error message code and it appears to be coming from the Facebook/React code.

Thanks!

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

If you scroll up, are there any earlier errors before these ones? You can see them in the error field in Redux logger.

@gaearon gaearon added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label May 26, 2016
@brotzky
Copy link
Author

brotzky commented May 26, 2016

No, those are the first errors.

I'm using react hot loader 3-beta.1 and when I hide and show the side logger I can reproduce the same error over and over.

screen shot 2016-05-26 at 12 07 27 pm

I think it's an error with one of my dependencies, but not sure which one. Postcss/autoprefixer and redux-form are back on my list of guesses.

edit: I've reverted back 2 weeks and get the same error. I think it has to be my OS or a dependency is failing.

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

Does npm ls react show only one copy of React? Can you create a minimal project reproducing the problem?

@brotzky
Copy link
Author

brotzky commented May 26, 2016

└── UNMET PEER DEPENDENCY react@15.1.0

npm ERR! peer dep missing: react@^0.14.8, required by react-addons-css-transition-group@0.14.8
npm ERR! peer dep missing: react@^0.14.8, required by react-addons-test-utils@0.14.8
npm ERR! code 1

My package.json specifies "react": "^15.1.0",

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

Ugh, npm ls react breaks because of peer deps. What’s confusing though is you seem to have react-addons-css-transition-group@0.14.8 and react-addons-test-utils@0.14.8. Can you please update these packages to 15.1.0 as well and make sure they don’t contain node_modules/react inside themselves?

@brotzky
Copy link
Author

brotzky commented May 26, 2016

Okay, I've upgraded both packages and checked their respective folders in node_modulesto see if they contain their own node_modules/react (which they don't).

"react-addons-css-transition-group": "^15.1.0",
"react-addons-test-utils": "^15.1.0",

npm ls reactnow returns
└── react@15.1.0

I still seem to be getting the same error

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

Cool. Still having the same issue? At this point only a reduced example would help.

@brotzky
Copy link
Author

brotzky commented May 26, 2016

I reverted back even further and it finally works. The major package changes were redux-form (v5 -> v6) and some smaller stuff.

Going to keep trying out different packages until I find out what was throwing the issue. Hopefully I post back here soon with the solution for the rare chance someone else has a similar problem.

Thanks a lot for the help! @gaearon

@jimfb
Copy link
Contributor

jimfb commented May 26, 2016

This sounds like it is probably a bug in React. That invariant is new; it was added in 15.1.0, which was released six days ago. #6650

@brotzky If you can provide a reproducible test case, that would be super helpful. Even if it is part of a larger codebase that you can share (my guess is it is going to be super hard to isolate that example).

cc @spicyj

@sophiebits
Copy link
Contributor

Yes, if you can post something that reproduces the problem it would be very helpful.

@brotzky
Copy link
Author

brotzky commented May 26, 2016

Yes, we updated to 15.1.0 yesterday, May 25th. That was when we started getting these new errors.

I will see if I can isolate the issue, but it's very hard to track down. That's the only error message I get. This doesn't break all components, only ones on a specific view. For example, it's the only view that uses <ReactCSSTransitionGroup />.

Here's an entire log I get from start to finish.
screen-shot-2016-05-26-at-1 54 02-pm

@brotzky
Copy link
Author

brotzky commented May 26, 2016

Ive just removed the redux-form component from the page and it loads fine.
redux-form@6.0.0-alpha.13

Will continue looking into this. It seems my original suspicion was correct.react@15.1.0 isn't playing nicely with redux-form@6.0.0-alpha.13

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

@erikras Ever seen this?

@brotzky
Copy link
Author

brotzky commented May 26, 2016

@erikras, when I specifically remove the

<Field
    name="inputName"
    component={inputName => 
     ...
}/>

Everything works as expected.

@gaearon
Copy link
Collaborator

gaearon commented May 26, 2016

This is definitely a React bug though. There's nothing Redux Form is doing that would be wrong. So if you can repro, please share a case!

@brotzky
Copy link
Author

brotzky commented May 27, 2016

I'm not sure it was React (or at least only React). Sure, the errors were thrown by React but it's possible that those errors were thrown correctly. Having said that, I've never seen those specific batch errors until upgrading to the newest version 15.1.0 (they're not very descriptive errors). The issue I had was with redux-form -- I had a slightly improper setup that was causing issues.

To resolve my specific errors I had to alter my mapStateToProps function in my redux-form container.

Before:

const mapStateToProps = (state) => ({
  fieldValue: state.form && state.form.quote.values.value,
});

After:

const mapStateToProps = (state) => ({
  fieldValue: state.form && state.form.field && state.form.field.values && state.form.quote.values.value,
});

Overall, if you're using redux-form v6.x and need to get your form fields value on props I recommend using formValueSelector() instead of how I approached the issue. http://redux-form.com/6.0.0-alpha.13/docs/api/FormValueSelector.md/. This will be much cleaner and less prone to issues.

Sorry I wasn't able to create an example. I'm still not sure how to replicate the error in a specific example and unfortunately I can't expose the code I'm currently working on.

@jimfb
Copy link
Contributor

jimfb commented May 27, 2016

I'm not sure it was React. Sure, the errors were thrown by React but it's possible that those errors were thrown correctly.

This is highly unlikely, unless code is reaching deep into the internals of React, it should not be possible for a user to trigger this error message. The error message is for internal debugging/sanity-check purposes.

This is probably a bug, but we're going to need some sort of repro from someone experiencing the bug. As I mentioned before, it's probably going to be really hard to isolate the bug, so even full-app repros are acceptable in this case.

@jimfb
Copy link
Contributor

jimfb commented May 27, 2016

If anyone else is experiencing the bug, please feel free to post! We'd like to collect as much data on this one as possible!

@brotzky
Copy link
Author

brotzky commented May 27, 2016

If I have time, I will see what I can do over the weekend. 🎱

@realbugger
Copy link

I also saw this error yesterday, and I just upgraded to react 15.1.0 the day before yesterday! In my case, I use redux-form as well except it's v5.2.4.

Eventually I found out the error was triggered by a line of code destructing an object, like const { foo } = bar;, but bar was undefined during certain rendering cycles. It's weird that I didn't get the usual cannot read property ”foo" of undefined error, though. And this only happened after upgrading to react 15.1.0.

@gaearon
Copy link
Collaborator

gaearon commented May 28, 2016

@realbugger Can you try to extract a minimal case reproducing this?

@brotzky
Copy link
Author

brotzky commented May 29, 2016

@gaearon I was able to recreate it. It took me a while to set everything up as I initially tried to reduce our application to the single bug, but that didn't work well. I then went to go look for decent boilerplates but all were overly complicated. Ended up using your ToDo example and added in redux-form@6.0.0-alpha.13, react-router and upgrading it to react@15.1.0

https://github.com/brotzky/react-issue-6895

  1. clone the repo and cd into it
  2. npm install in the root
  3. go to /examples/todomvc
  4. npm install in /examples/todomvc
  5. npm start in /examples/todomvc
  6. open http://localhost:3000/

To recreate the bug:

  1. Focus the example input
  2. Type into the example input

You should get errors in your console. I've also commented out a line that fixes the bug. Everything should be contained in examples/todomvc/containers/Header.js. I added in the router because that's how our app was setup -- it's probably not necessary to recreate the bug.

Downgrading to react@15.0.1 removes the batch errors and only the undefined error stays.

Let me know if you have questions. 🐛🔨

@gaearon
Copy link
Collaborator

gaearon commented May 29, 2016

Downgrading to react@15.0.1 removes the batch errors and only the undefined error stays.

Thank you so much! So do you mean that you see an earlier error from your code before that invariant?

@erikras
Copy link

erikras commented May 29, 2016

@erikras Ever seen this?

No.

@brotzky
Copy link
Author

brotzky commented May 29, 2016

@gaearon. Yes, looks like the redux connect() method fails due to an undefined value in mapStateToProps(). But you can also get the batch error after typing into the input field.

screen shot 2016-05-29 at 1 12 02 pm

@gaearon
Copy link
Collaborator

gaearon commented May 29, 2016

@brotzky

This is what I was asking in the beginning of the thread:

If you scroll up, are there any earlier errors before these ones?

The reason I asked is that if your code threw (e.g. in mapStateToProps), then it’s pretty much expected that React gets into an inconsistent internal state. So this is not a bug in React, because the error didn’t appear out of the blue: it appeared after another error was thrown in the user code.

@brotzky
Copy link
Author

brotzky commented May 29, 2016

Damn, sorry for the misunderstanding. It appears in my original example there was no previous error like the one I linked. I agree it's probably not a React bug.

@gaearon
Copy link
Collaborator

gaearon commented May 29, 2016

Hmm. So we’re still after something like your original example I’m afraid 😞 .
Unless... could it be that the error there was swallowed by a Promise? 😄

@brotzky
Copy link
Author

brotzky commented May 29, 2016

You got it 👌 Oops, on mobile and closed by accident. It's still a bit weird that the error occurred after specifically on 15.1.0. May be worth checking the error message to be more helpful for the regular user. I didn't change my code from 15.0.1 and te upgrade caused the obscure error.

@jkomyno
Copy link

jkomyno commented Sep 28, 2016

I'm having the same bug. What is strange, though, is that it happens only if I move the subcomponents of my custom Dashboard components from a place to another, in a way that just doesn't make sense to me at all.
The error that I get is:

main.js:2982 Warning: performUpdateIfNecessary: Unexpected batch number (current 7, pending 1)printWarning @ main.js:2982warning @ main.js:3006performUpdateIfNecessary @ main.js:15682runBatchedUpdates @ main.js:15289perform @ main.js:16572perform @ main.js:16572perform @ main.js:15228flushBatchedUpdates @ main.js:15311closeAll @ main.js:16638perform @ main.js:16585batchedUpdates @ main.js:25400enqueueUpdate @ main.js:15339enqueueUpdate @ main.js:24382enqueueSetState @ main.js:24567ReactComponent.setState @ main.js:3435handleChange @ main.js:30391handleChange @ main.js:10196dispatch @ main.js:30773dispatch @ VM82326:1(anonymous function) @ main.js:112547dispatch @ main.js:31239(anonymous function) @ main.js:47872

I'm using React@15.3.1, redux@3.5.2, axios@^0.13.1 (for AJAX requests) and redux-thunk@^2.1.0, and in two months working on this project for my agency I've never seen anything like this.

@jkomyno
Copy link

jkomyno commented Sep 30, 2016

My issue was pretty similar, same undefined stuff, even though it was a
prop correctly initialized in the reducer. I suppose the only workaround
here would be patching the debugger a little bit to make the developers
realize where the error comes from. Or, even better, find a way to tunnel
the reducer initialization to the component at the first render

Il 30/set/2016 18:08, "Duncan Finney" notifications@github.com ha scritto:

@jkomyno https://github.com/jkomyno @gaearon
https://github.com/gaearon: I experienced this issue as well.

What was happening was the initialValue I was pulling from state was
undefined

VenueForm = reduxForm({
form: 'venue',
enableReinitialize: true
})(VenueForm);

VenueForm = connect(
(state, props) => {
const venue = _.find(state.resources.venues.items, i => i.id === id);
return {
initialValues: venue
}
}
}))(Venue);

Changed one line to:

const venue = _.find(state.resources.venues.items, i => i.id === id) || {};

and everything worked again.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#6895 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ALzuelofodyOkH2BK1Bb419-gYTGqp2pks5qvTP6gaJpZM4In00Z
.

@zjjott
Copy link

zjjott commented Nov 1, 2016

I have this error when I use ref method in batch Component update like this:

scrollIntoView(element){
   //this function raise some other exception when element is null
  //and then Unexpected batch number will raise
},
render(){
    return <ul >{this.state.data.map((row)=>{
           if(row.id==this.state.id){
               return <li ref={this.scrollIntoView}>{row.data}</li>
           }
           else{
                   return <li>{row.data}</li>
           }
        })
        }
        </ul>
}

I fixed it when scrollIntoView then no longer raise Exception,so maybe this error in issue is cause by exception during render

@giuseppeg
Copy link
Contributor

fwiw I got this error when I tried to override PureComponent.shouldComponentUpdate like so:

export default class extends PureComponent {
  shouldComponentUpdate(nextProps, nextState) {
    console.log(typeof super.shouldComponentUpdate) // > undefined
    /* some user code */
    return super.shouldComponentUpdate(nextProps, nextState)
  }

  render() {
    // ...
  }
}

Probably this is not optimal but it should be allowed and working right?
Would appreciate any help/hint.

cc @spicyj

@megrbui
Copy link

megrbui commented Nov 17, 2016

But you can also get the batch error after typing into the input field.

I got this error when trying to access e.target.value from an event that bubbles up from an input element into a custom element. By the time I want to consume it, the event has already been reset to null.

const GeneralInput = ({ name, onChange }) => ( <input name={ name } onChange={ onChange } /> )

export default class OtherComponent extends Component {
  constructor (props) {
    this.state={}
    this._handleChange = this._handleChange.bind(this)
  }
  _handleChange (event) { this.setState({ [event.target.name]: event.target.value }) }
  render () { 
    return (
      <form onChange={ this._handleChange }>
        <GeneralInput name='firstname' value={this.state.firstname} />
      </form>
    )
  }
}

I solved it by calling e.persist() on the input element itself:
const GeneralInput = ({ name, onChange }) => ( <input name={ name } onChange={ (e) => e.persist(); onChange(e) } /> )

@gaearon
Copy link
Collaborator

gaearon commented Nov 17, 2016

@mgnrsb and everyone else:

If you only saw this error but didn't see the original error (for example in @mgnrsb's case it would be something like "Cannot read target property of null") then you still have a problem, and some part of your code swallows exceptions.

The most common way to get this problem is when you use Promises and have a catch() block after you're attempting to update the UI. If a component throws an error (due to mistake in your code) your catch() handler gets this error and tries to render the error in the UI, assuming it is a network error. However the UI is already broken at this point because of the earlier error (which you never surface) and this is why you get a confusing second error.

Be careful catching errors especially when dealing with Promises. It is very easy to accidentally catch errors in your own code.

@viz
Copy link

viz commented Nov 17, 2016

I'm seeing this too. Seems to be related to redux-form and or it's interaction with react.

Current versions are: redux-form v6.2.0, react v15.4.0

Seems like this problem started occurring after upgrading to redux-form 6.x.

developer_tools_-http___localhost_3000

@gaearon
Copy link
Collaborator

gaearon commented Nov 18, 2016

I'm afraid additional comments on this thread won't be helpful without examples reproducing this issue.

@brotzky
Copy link
Author

brotzky commented Nov 18, 2016

@viz We're using redux-form v6.2.0 and react v15.4.0 with no issues at the moment. We've also been using redux-form v6.x since alpha with no issues from react.

I would go over and try to identify the exact source of the issue. Try removing components until you narrow it down. Then I'd advise checking all the variables you're using in that component and making sure you're not passing around undefined anywhere.

Or, as @gaearon suggested, provide an easy to follow example reproducing the issue.

@wking
Copy link

wking commented Nov 24, 2016

Here's a fairly minimal project which reproduces this error in the test suite (shortly before the test legitimately errors out):

$ node --version
v4.4.6
$ npm --version
2.15.5
$ git clone git://github.com/wking/performUpdateIfNecessary-bug.git bug
$ cd bug
$ npm install
npm WARN optional dep failed, continuing fsevents@1.0.14
react@15.4.1 node_modules/react
├── object-assign@4.1.0
├── loose-envify@1.3.0 (js-tokens@2.0.0)
└── fbjs@0.8.6 (ua-parser-js@0.7.12, promise@7.1.1, isomorphic-fetch@2.2.1, core-js@1.2.7)

react-dom@15.4.1 node_modules/react-dom
├── object-assign@4.1.0
├── loose-envify@1.3.0 (js-tokens@2.0.0)
└── fbjs@0.8.6 (ua-parser-js@0.7.12, promise@7.1.1, isomorphic-fetch@2.2.1, core-js@1.2.7)

react-scripts@0.7.0 node_modules/react-scripts
$ npm test
…a…
…
  console.error node_modules/react-dom/node_modules/fbjs/lib/warning.js:36
    Warning: performUpdateIfNecessary: Unexpected batch number (current 2, pending 1)

@gaearon gaearon reopened this Nov 24, 2016
@gaearon
Copy link
Collaborator

gaearon commented Nov 24, 2016

The reproducing code is a bit convoluted but doesn't seem like there's any good reason for it to fail.
Reopening and tagging as a bug.
Help investigating why the error happens is welcome.

Note that it's not an error, as it was relaxed to be a warning. Still it's weird it happens.

@gaearon gaearon added Type: Bug and removed Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug labels Nov 24, 2016
@wking
Copy link

wking commented Nov 24, 2016 via email

wking added a commit to wking/depviz that referenced this issue Nov 26, 2016
This lets us use initial slugs that may map to multiple nodes (e.g. a
per-repo slug) instead of the old keys which had to be one-to-one with
nodes (e.g. a per-issue slug).

Also some test shenanigans to get everything passing with 100%
coverage.  For reasons I don't understand, my attempt at atomic state
pivots are still not sticking, which is why we still can't throw an
error in the duplicate-dummy-requests-for-a-single-key case.  I'm
suspicious of [1].  But a change at duplicate requests isn't the end
of the world either.

[1]: facebook/react#6895
wking added a commit to wking/depviz that referenced this issue Nov 28, 2016
This lets us use initial slugs that may map to multiple nodes (e.g. a
per-repo slug) instead of the old keys which had to be one-to-one with
nodes (e.g. a per-issue slug).

Also some test shenanigans to get everything passing with 100%
coverage.  For reasons I don't understand, my attempt at atomic state
pivots are still not sticking, which is why we still can't throw an
error in the duplicate-dummy-requests-for-a-single-key case.  I'm
suspicious of [1].  But a change at duplicate requests isn't the end
of the world either.

[1]: facebook/react#6895
@romansky
Copy link

Was able to "reproduce" this issue by simple:

componentWillUnmount(){
        throw "bbbb";
}

There was no other indication for the generated exception, OP's error ensured.

@zargold
Copy link

zargold commented Jan 20, 2017

I got this issue with react-redux-form + React Autocomplete by setting the initial state for a form to be null rather than ''. (Which I really wanted... but it didn't work... oh well set it back to '' and everything "fixed".

@mcku
Copy link

mcku commented Jan 23, 2017

I can reproduce a case, likely similar to the original.

OnsenUI 2.0.5 Lazylist does not render and gives the "performUpdateIfNecessary: Unexpected batch number" error after upgrading to Leaflet 1.0.2 & React-Leaflet 1.1.0.

Going back to legacy Leaflet 0.7.7 alleviates the error, and the Lazylist component functions correctly.

In both cases react version was 15.4.2.

@ivks
Copy link

ivks commented Jan 25, 2017

This may be out of context, but I came to this issue, because this message popped up while I did a stupid mistake in my React Native code
Inside the view for an onPress event I did this
onPress={methodName}
instead of
onPress={methodName()}
Posting this just in case help anyone else save some time.

@osilvaa
Copy link

osilvaa commented Jan 25, 2017

This message popped up when I was working with a SELECT on Redux-Form. Initially, my SELECT was initialised with an empty array as options. But, accidentally, on my action creator I made this:

--> let staticData = {}; <--
  switch(Number(countryId)) {
    case 1:
      staticData = [
        { id: 1, name: 'XPTO1'},
        { id: 2, name: 'XPTO2'}      
      ];
      break;
  }

return {
      type: FETCH_KEY,
      payload: {
        data: staticData
      }
  };

This was changing the initial type from Array to Object which was unexpected by my reducer & view. After changing the highlighted line to
--> let staticData = []; <--
It started working fine.

Redux-Form: 6.1.1 & React 15.3.2

@oklas
Copy link

oklas commented Feb 21, 2017

This error

Error: performUpdateIfNecessary: Unexpected batch number

appears at some component after error (see #4026)

Uncaught TypeError: Cannot read property '_currentElement' of null

appears in another component if it have crash at render() method (for example caused by (undefined).x code)

both components is not parent of each other

@gaearon
Copy link
Collaborator

gaearon commented Feb 21, 2017

In this thread, everybody seems to be enumerating all the different possible errors in JavaScript apps. However they are not relevant to solving the issue, and are not helpful to others. This thread focuses on symptoms, but the underlying cause has been explained several times in this and other threads. I'm going to lock this thread to reduce the noise and help people finding this on Google focus on the solution rather than the symptom.

I have explained the solution in #7617 (comment) so please read that comment. This problem most commonly occurs with Promises, but can occur in any code where you catch exceptions and don't log them.

If you see a cryptic error like this it always means there is an earlier error from your component code that causes React to break. You need to scroll your console up and find the original error.

If you don't see an earlier error in your own components, it means that your code is swallowing errors. This is very common if you use catch() with Promises and accidentally swallow errors inside React. I've also seen this with other libraries, like Redux Saga, where people just catch any error without checking if it's a network failure or something else. Some third party libraries may also swallow your errors. I recommend to enable "Break on All Exceptions" in your debugger, and then when the error throws, check the call stack to find who's silently catching your error.

Again, this error itself is just an irrelevant symptom.
You need to figure out why your code crashes in a component, and which catch swallows the crash.

The fact that React produces cryptic errors on next updates after a component crash is unfortunate, and we'll fix this in next versions of React. However, in any case, you need to fix the underlying problem (your code crashing) first.

If you're sure it's a bug in React please file a new issue with a minimal reproducing test case.

@gaearon gaearon closed this as completed Feb 21, 2017
@gaearon gaearon removed the Type: Bug label Feb 21, 2017
@facebook facebook locked and limited conversation to collaborators Feb 21, 2017
@gaearon
Copy link
Collaborator

gaearon commented Jul 27, 2017

A small update on this. We just released React 16 beta which shouldn’t emit cryptic errors like this one. Even if the application code swallows an error, React 16 will still print it to the console. It might be too early for you to try React 16 (since ecosystem is still preparing for it), but this error should never occur in the future after you switch to it.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests