The Wayback Machine - https://web.archive.org/web/20220427190005/https://github.com/facebook/react/issues/17355
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

"Should not already be working" in Firefox after a breakpoint/alert #17355

Open
gzzo opened this issue Nov 13, 2019 · 59 comments
Open

"Should not already be working" in Firefox after a breakpoint/alert #17355

gzzo opened this issue Nov 13, 2019 · 59 comments

Comments

@gzzo
Copy link

@gzzo gzzo commented Nov 13, 2019

Do you want to request a feature or report a bug?
Bug

What is the current behavior?
I'm seeing "Error: Should not already be working" after upgrading to React 16.11

Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?

This is exclusively happening on an older version of Chrome, 68.0.3440 on Windows 7

I was unable to reproduce this in a VM environment but our Sentry is getting littered with these errors.

I know it's a long shot, but I wasn't able to find any information about this error anywhere, just a reference in the error codes file in react, so thought it would be a good idea to report this just in case. Curious if anyone has seen this.

@aweary
Copy link
Contributor

@aweary aweary commented Nov 13, 2019

Is there any way you can provide a code sample that reproduces the problem? That error should only occur if there's a bug in React, so it'd be very helpful if we could reproduce.

@CoryDanielson
Copy link

@CoryDanielson CoryDanielson commented Nov 17, 2019

I see the same error message in sentry, and the breadcrumbs show an "out of memory" error - and then further down some react errors.

Not sure if it'll be useful, but here's some the breadcrumbs.

OS: Windows 7,
Browser: Firefox 70.0
React: 16.9.0

out of memory
out of memory
08:21:52
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:21:52
sentry
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:21:52
xhr
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:21:52
sentry
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:21:53
xhr
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:21:57
xhr
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:22:22
fetch
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:23:25
xhr
Error: Minified React error #327; visit https://reactjs.org/docs/error-decoder.html?invariant=327 for the full message or use the non-minified dev environment for full errors and additional helpful warnings. 
08:23:30
xhr
08:24:39
exception
Error: Should not already be working.
@gzzo
Copy link
Author

@gzzo gzzo commented Nov 18, 2019

To add some more data points:

I'm not seeing out of memory errors on my end.

We downgraded to React 16.10.2 and are still seeing errors. Will keep downgrading and report back.

Also to the FB team, we're happy to share Sentry reports with you.

@CoryDanielson
Copy link

@CoryDanielson CoryDanielson commented Nov 18, 2019

I just updated my comment to include the React version (v16.9.0)


Edit: Also I searched outside of the last 24h and we've received this error many times.

Browser: Firefox 70.0 & 68.0
OS: Windows 10

Browser: Firefox 70.0
OS: Mac OS X 10.14

Browser: IE 11
OS: Windows 10

@mohsinulhaq
Copy link

@mohsinulhaq mohsinulhaq commented Nov 21, 2019

I am getting the exact same sentry reports, but unable to reproduce the same in VM environment.

@jhou
Copy link

@jhou jhou commented Nov 27, 2019

We're seeing this in Sentry, too.

OS: Windows 10
Browser: Edge 18.18362
React 16.11.0 (from yarn.lock)

AFAICT it happens before the user did anything; here's the stack trace:

  at Lj(../node_modules/react-dom/cjs/react-dom.production.min.js:5382:1)
  at Anonymous function(../node_modules/react-dom/cjs/react-dom.production.min.js:2829:1)
  at t.unstable_runWithPriority(../node_modules/scheduler/cjs/scheduler.production.min.js:266:1)
  at fg(../node_modules/react-dom/cjs/react-dom.production.min.js:2794:1)
  at ig(../node_modules/react-dom/cjs/react-dom.production.min.js:2824:1)
  at Y(../node_modules/scheduler/cjs/scheduler.production.min.js:203:1)
  at A.port1.onmessage(../node_modules/scheduler/cjs/scheduler.production.min.js:94:1)```
@shriniketsarkar
Copy link

@shriniketsarkar shriniketsarkar commented Dec 4, 2019

@gzzo Are you by any chance in any of your componentDidMount functions attempting to update the state as the first thing to do in that function?

I was getting the error Should not already be working when I had the following line in my componentDidMount function :
this.setState({ hasLaunched: true });

@gzzo
Copy link
Author

@gzzo gzzo commented Dec 4, 2019

Interesting. We do call setState in a couple of componentDidMount. The React docs specify this is okay though:

You may call setState() immediately in componentDidMount(). It will trigger an extra rendering, but it will happen before the browser updates the screen. This guarantees that even though the render() will be called twice in this case, the user won’t see the intermediate state. Use this pattern with caution because it often causes performance issues. In most cases, you should be able to assign the initial state in the constructor() instead. It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.

@rfboykin
Copy link

@rfboykin rfboykin commented Dec 16, 2019

Hello,

We've also noticed this error in our sentry. It's only occurred once so far under these conditions:

OS: Windows 10
Browser: IE 11
React: 16.11.0

The stack trace does not appear to provide much additional info:

Error: Should not already be working.
  at Lj(webpack://[name]/./node_modules/react-dom/cjs/react-dom.production.min.js:223:104)
  at Anonymous function(webpack://[name]/./node_modules/react-dom/cjs/react-dom.production.min.js:121:110)
  at t.unstable_runWithPriority(webpack://[name]/./node_modules/scheduler/cjs/scheduler.production.min.js:18:431)
  at fg(webpack://[name]/./node_modules/react-dom/cjs/react-dom.production.min.js:120:318)
  at ig(webpack://[name]/./node_modules/react-dom/cjs/react-dom.production.min.js:121:61)
  at Y(webpack://[name]/./node_modules/scheduler/cjs/scheduler.production.min.js:17:178)
  at S.port1.onmessage(webpack://[name]/./node_modules/scheduler/cjs/scheduler.production.min.js:14:64)
@dvineyardUPD
Copy link

@dvineyardUPD dvineyardUPD commented Jan 15, 2020

I had this same issue. Was not a problem in Chrome however I received a blank screen and the error. Error: Should not already be working.
React 16.12.0
I had two(2) this.setState calls in conditional if statements in componentDidMount. This should have been ok however I removed them and figured a way to set them a little later and the error stopped. this.setState should have been ok to run in componentDidMount so I hope this gets resolved.

@magnetnation
Copy link

@magnetnation magnetnation commented Jan 29, 2020

We also experience this issue.
React 16.12.0
OS: IOS 13.3
Browser: Safari

We have tons of cases were we call one or multiple 'setState' in 'componentDidMount'. It has never been an issue. Moving these calls to other places is not an option.

@xUSERxNAMEx
Copy link

@xUSERxNAMEx xUSERxNAMEx commented Feb 7, 2020

I am able to reproduce the issue when stepping through a function after a breakpoint in an otherwise working development build application.

Console output:
Error: Should not already be working. react-dom.development.js:24247
performSyncWorkOnRoot React
performSyncWorkOnRoot self-hosted:920
flushSyncCallbackQueueImpl React
unstable_runWithPriority scheduler.development.js:697
React 2
runWithPriority$2
flushSyncCallbackQueueImpl
workLoop scheduler.development.js:641
flushWork scheduler.development.js:596
performWorkUntilDeadline scheduler.development.js:203
enter event-loop.js:79
enter self-hosted:874
_pushThreadPause thread.js:256
_pauseAndRespond thread.js:851
pauseAndRespond thread.js:1049
_makeOnStep thread.js:978
authCheckState auth.js:100
createThunkMiddleware Redux
dispatch (index):1
onTryAutoSignIn App.js:42
componentDidMount App.js:17
React 6
commitLifeCycles
commitLayoutEffects
callCallback
invokeGuardedCallbackDev
invokeGuardedCallback
commitRootImpl
commitRootImpl self-hosted:975
unstable_runWithPriority scheduler.development.js:697
React 10
runWithPriority$2
commitRoot
finishSyncRender
performSyncWorkOnRoot
scheduleUpdateOnFiber
updateContainer
legacyRenderSubtreeIntoContainer
unbatchedUpdates
legacyRenderSubtreeIntoContainer
render
js index.js:51
Webpack 7
webpack_require
fn
1
webpack_require
checkDeferredModules
webpackJsonpCallback

@alexandcote
Copy link

@alexandcote alexandcote commented Feb 25, 2020

We also experience this issue since we bumped React.

React 16.12.0
Browser: Firefox 72/73/74
OS: Window 10, Mac OS 10.0/10.10/10.14

The stack traces point us to this function call

More detail

InvalidStateError
An attempt was made to use an object that is not, or is no longer, usable

@rralbritton
Copy link

@rralbritton rralbritton commented Feb 26, 2020

Any movement on this? I am also getting these errors in FireFox (73.0.1 (64-bit) but not in Chrome (Version 80.0.3987.122 (Official Build) (32-bit)
React - 16.12
React-Redux 7.1.3

It is happening when trying to initialize data from props:

//Parent Page
<SimpleForm sampleData = {sampleData} />

//SimpleForm.js
 componentDidMount (){
 if (this.props.sampleData) {
      this.props.initialize(this.props.sampleData);
}

Error:

performSyncWorkOnRoot React
    performSyncWorkOnRoot self-hosted:920
    flushSyncCallbackQueueImpl React
    unstable_runWithPriority scheduler.development.js:701
    React 2
        runWithPriority$2
        flushSyncCallbackQueueImpl
    workLoop scheduler.development.js:645
    flushWork scheduler.development.js:600
    performWorkUntilDeadline scheduler.development.js:197
    enter event-loop.js:79
    enter self-hosted:874
    _pushThreadPause thread.js:256
    _pauseAndRespond thread.js:851
    hit breakpoint.js:235
    componentDidMount Redux
    React 6
        commitLifeCycles
        commitLayoutEffects
        callCallback
        invokeGuardedCallbackDev
        invokeGuardedCallback
        commitRootImpl
    commitRootImpl self-hosted:975
    unstable_runWithPriority scheduler.development.js:701
    React 10
        runWithPriority$2
        commitRoot
        finishSyncRender
        performSyncWorkOnRoot
        scheduleUpdateOnFiber
        updateContainer
        legacyRenderSubtreeIntoContainer
        unbatchedUpdates
        legacyRenderSubtreeIntoContainer
        render
    js index.js:10
    Webpack 7
        __webpack_require__
        fn
        0
        __webpack_require__
        checkDeferredModules
        webpackJsonpCallback
        <anonymous>
@nikhil3000
Copy link

@nikhil3000 nikhil3000 commented Mar 6, 2020

I got the same error 'Should not already be working' because I created a pipe write stream in my dataActions, shifting the function to a util file outside the action file fixed the issue for me.

@hinok
Copy link

@hinok hinok commented Mar 26, 2020

I got the same error reported on sentry

Error: Should not already be working.
  at Lj(/node_modules/react-dom/cjs/react-dom.production.min.js:223:129)
  at b(/node_modules/react-dom/cjs/react-dom.production.min.js:121:115)
  at Lf(/node_modules/scheduler/cjs/scheduler.production.min.js:18:437)
  at fg(/node_modules/react-dom/cjs/react-dom.production.min.js:120:325)
  at ig(/node_modules/react-dom/cjs/react-dom.production.min.js:121:61)
  at X(/node_modules/scheduler/cjs/scheduler.production.min.js:17:184)
  at hf2P/S.port1.onmessage(/node_modules/scheduler/cjs/scheduler.production.min.js:14:64)
User-Agent: 
Mozilla/5.0 (Windows NT 6.2; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0

I can point to the live website where this error was reported but I cannot reproduce it manually.

@azizhk
Copy link

@azizhk azizhk commented Apr 27, 2020

Getting this error in React Native as well.
react: "16.11.0"
react-native: "0.62.2"

Based on my understanding of this reddit comment.

I think if user land code throws an error in componentDidMount, React does not reset state and next time render occurs, this Error "Should not already be working" gets thrown.

@rtremblet-fr
Copy link

@rtremblet-fr rtremblet-fr commented May 11, 2020

I has this issue and the problem was related toan ajax call with jquery made in componentDidMount with async parameter to false, this causes some issues with latest react release to synchronise the state I assume. setting async to true solved the issue

@dimaryaz
Copy link

@dimaryaz dimaryaz commented May 19, 2020

This happens to me if I set a breakpoint in componentDidMount, either by clicking the line number in Firefox's debugger or by calling debugger in the code.

@dimaryaz
Copy link

@dimaryaz dimaryaz commented May 19, 2020

Ok, at least in my case, this looks like a... thread-safety issue? Firefox has no problem running JavaScript event handlers while stopped at a breakpoint, causing all kinds of bizarre behavior. I must've missed the memo that JavaScript is no longer single-threaded.

@azizhk
Copy link

@azizhk azizhk commented May 20, 2020

@aweary Can we add some more diagnostic info, like what component React is working on, maybe that might give us some information on where to concentrate.
Right now, we are getting multiple reports about users facing App Crashes (React Native)

@cristianoccazinsp
Copy link

@cristianoccazinsp cristianoccazinsp commented May 25, 2020

Just got this error in a React Native project.
"react": "16.13.1",
"react-native": "0.61.5"

@azizhk
Copy link

@azizhk azizhk commented May 25, 2020

@cristianoccazinsp I've created an issue on react-native repo as well, because its a different renderer: facebook/react-native#28948
Please do subscribe there as well.

@guoyunhe
Copy link

@guoyunhe guoyunhe commented May 29, 2020

Same here if we run $.ajax() in componentDidMount(). Our solution is to use a setTimeout():

{
  componentDidMount() {
    setTimeout(() => {
      $.ajax();
    }, 300);
  }
}
@azizhk
Copy link

@azizhk azizhk commented Jun 5, 2020

Hi @acdlite (sorry for tagging you here),
Just wanted to know what React features would trigger the usage of unstable_runWithPriority. Maybe that might help in figuring out what is causing this issue and help with creating a reproduction.

@karthikravichandran94
Copy link

@karthikravichandran94 karthikravichandran94 commented Aug 29, 2020

Hi Team,

I am facing this issue now in firefox browser. How to resolve this issue ? Any suggestion please?

@KyleAsaff
Copy link

@KyleAsaff KyleAsaff commented Sep 7, 2020

My error reporting system has been reporting me this error in production for my react app https://twisti.app. anyone know what is causing it or how to fix it? the error message is not very helpful

user info:

Firefox 60.0
Windows 7
Windows

Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0

error:

error
Should not already be working.

/static/js/2.27fae31b.chunk.js at line 2

/*! For license information please see 2.27fae31b.chunk.js.LICENSE.txt */
(this.webpackJsonptwisti=this.webpackJsonptwisti||[]).push([[2],[function(e,t,n){"use strict";e.exports=n(163)},function(e,t,n){"use strict" {snip}
//# sourceMappingURL=2.27fae31b.chunk.js.map

trace:


Status | internal_error
-- | --
Trace ID | 26d237fb8f5a4643b2fa8fc001a47e59
Span ID | ae29218588485a11
Operation Name | pageload



@oopsRookie
Copy link

@oopsRookie oopsRookie commented Sep 27, 2020

This happens to me if I set a breakpoint in componentDidMount, either by clicking the line number in Firefox's debugger or by calling debugger in the code.

same with me, when i set a breakpoint between setState and Axios request in componentDidUpdate, this error will appear. But if i delete the breakpoint, everything is fine.

@leojh
Copy link

@leojh leojh commented Sep 30, 2020

Also seeing this reported all of a sudden by my application monitoring service.
All on Windows 10 and Firefox 80 so far.

@gaearon
Copy link
Member

@gaearon gaearon commented Mar 24, 2021

Does anyone have reliable reproduction steps? We can't really help without them.

@rtremblet-fr
Copy link

@rtremblet-fr rtremblet-fr commented Mar 24, 2021

I has this issue and the problem was related to an ajax call with jquery made in componentDidMount with async parameter to false, the réponse of tha call updated the state, this causes some issues with latest react release to synchronise the state I assume. setting async to true solved the issue

@mooflu
Copy link

@mooflu mooflu commented Mar 24, 2021

See codesandbox above - run in firefox.

@gaearon
Copy link
Member

@gaearon gaearon commented Mar 24, 2021

Oh nice. Thanks.

@gaearon gaearon changed the title Should not already be working "Should not already be working" in Firefox after a breakpoint/alert Mar 24, 2021
@gaearon
Copy link
Member

@gaearon gaearon commented Mar 24, 2021

All right, so the consistent repro is:

  1. Open https://codesandbox.io/s/should-not-already-be-working-bl72j?file=/src/index.js in Firefox
  2. Observe the error message

There is some kind of timing assumption that gets broken by the alert() being a blocking call. I don't know where the problem is. Does anyone want to dive in the source and figure it out?

@mdaj06
Copy link
Contributor

@mdaj06 mdaj06 commented Apr 21, 2021

@gaearon I can have a look at this

@gaearon
Copy link
Member

@gaearon gaearon commented Apr 21, 2021

Sure, thanks!

@julianfssen
Copy link

@julianfssen julianfssen commented Jun 2, 2021

Hi, guys!

I ran into this problem on my app and thankfully, this issue is already raised here.

I tried to debug the issue locally but I'm unable to reproduce the issue in my local build. Here's what I did:

  1. I included the code sample mentioned here by @mooflu in my App.js file in fixtures/dom/src/components.
  2. I started the DOM fixtures server according to the README.
  3. However, I cannot reproduce the error locally even when selecting the production build. But, the error is triggered when I choose any remote React version. I've attached a snippet below to show the behavior.
Screen.Recording.2021-06-02.at.9.52.27.PM.mov

Based on the error trace, it seems like the error was triggered at performSyncWorkOnRoot:

image

I've done a quick investigation and it seems like the executionContext bit value is not equal to NoContext. I assume this means executionContext is still in the rendering stage? Here are the pics:

image
image
image

Meanwhile, here are the context bits in Chrome at the same breakpoint:

image
image
image

I'd be happy to investigate further into this if no one is taking it up, although it may take some time as I'm unfamiliar with React internals. Also, is there a way for me to test the production version locally e.g. using the production build to test the dev.html file in fixtures/packaging/babel-standalone?

Thanks!

@mdaj06
Copy link
Contributor

@mdaj06 mdaj06 commented Jun 2, 2021

@julianfssen i have been busy lately I think you have made some progress, I guess you can take it up from here

@julianfssen
Copy link

@julianfssen julianfssen commented Jun 3, 2021

@julianfssen i have been busy lately I think you have made some progress, I guess you can take it up from here

Hey @mdaj06 ! Sorry for the slow reply. I apologize as I didn't see your comment about taking the issue up, in that case I will help you take a look at this and see what I can do. Thanks!

@Rashik4567
Copy link

@Rashik4567 Rashik4567 commented Jun 9, 2021

My site is working in Chrome fine.. not even a warning.
but in Firefox, it says Error: Should not already be working. The error is on my app.js file where i used class component and used component did mount.
image

but after copying my cookies from Chrome to Firefox.. the site started working.
so I think this has some relationships to cookies.. or local site data.

@julianfssen
Copy link

@julianfssen julianfssen commented Jun 9, 2021

My site is working in Chrome fine.. not even a warning.
but in Firefox, it says Error: Should not already be working. The error is on my app.js file where i used class component and used component did mount.
image

Yup! This seems to only trigger in Firefox, I've investigated the issue and I think I may have found the cause, will post a writeup here on it in awhile to be verified by the team. In the meantime, you can wrap the alert() call in a setTimeout() block e.g:

setTimeout(() => console.log('your message'), 0)

to 'fix' it.

@julianfssen
Copy link

@julianfssen julianfssen commented Jun 9, 2021

TL;DR: Firefox does not block WebSockets execution for alert and debugger calls, causing the scheduler to performWorkOnDeadline incorrectly and setting the wrong executionContext when calling performSyncWorkOnRoot. Microtasks solve this problem, but flushing via flushSyncCallbackQueue still causes the same issue.

I had a look at this issue and made a few observations about why this is happening.

This issue happens on Firefox for React v16.10 to the latest v17.02 release. In v16.10, @acdlite added the feature to use message channels to manage the cycle between performing work and yielding to the browser.

This works perfectly on every browser except Firefox, which has an issue with it. window.alert() is a blocking call and works correctly most of the times. However, it does not block the execution of WebSocket calls, which is not the case with Chrome and other browsers. Here are some bug reports I found regarding this issue:

One way to observe the bug is to run the fixtures/dom mini-app and modify your App.js like so (thanks to @mooflu for the code I used to replicate this behavior:

image

Try to change the React version and observe the behavior. If you pulled the latest commit as of today, there should be no issues for your local environment. There should also be no issues for v16.10 and below.

Below are snippets to demonstrate the behavior.

Observe the behavior and console logs in each browser.

Behavior on Chrome:

Screen.Recording.2021-06-09.at.9.05.20.PM.mov

Behavior on Safari:

Screen.Recording.2021-06-09.at.9.06.31.PM.mov

Behavior on Firefox (buggy):

Screen.Recording.2021-06-09.at.9.07.27.PM.mov

After calling portMessage in Firefox, the execution does not seem to pause as expected when alert(), unlike other browsers. performWorkUntilDeadline is called and this messes up the executionContext when calling performSyncWorkOnRoot.

However, I was curious why this happened in production but not when cloning the repo and testing it locally. It turns out this issue is fixed with the enableSyncMicroTasks feature to flush tasks instead of flushSyncCallbackQueue which seems to be one invoking the message issue above. I tested the branch above and the issue does not happen in Firefox with alert() and debugger.

There should be no issues when using microtasks, but the should not already be working error should trigger if you remove the supportsMicrotasks flag. Remove the supportsMicrotasks check to fallback to the previous non-microtask way of flushing the queue—and the issue will appear again, possibly due to flushSyncCallbackQueue.

Try checking out the branch (or the latest commit) and replicate the steps above.

How to replicate the issue:

  1. There are two ways to test this. You can run the mini-app in fixtures/dom or use the babel-standalone/dev.html.Add the following snippet to your App.js file if you're using the former, or add it to your <script> tag for the latter.
class AppClass extends React.Component { // don't forget to export the class if you're calling <AppClass />
  constructor(props) {
    super(props);
    this.state = {
      num: 99
    };
  }

  componentDidMount() {
    this.setState((state) => {
      return { num: state.num + 2 };
    });
    alert('AppClass');
  }

  render() {
    return (
      <div className="App">
        <h1>Num: {this.state.num}</h1>
      </div>
    );
  }
}
  1. Run the fixtures/dom server or open babel-standalone/dev.html in Firefox.
  2. Observe the console. There should be an should not already be working error. Note: This error does not appear on v16.9.0 and below or if your branch is later than the land microTasks commit (although the issue still exists).
  3. Disable the supportMicrotasks check in ensureRootIsScheduled (line 688 in both ReactFiberWorkLoop.old.js and ReactFiberWorkLoop.new.js).
  4. Rebuild React with yarn build and try restarting the server or refreshing the fixture file again. The error should appear now in Firefox.

However, I'm not sure whether this is the real issue, despite my discoveries. @acdlite, may I know if these assumptions are aligned with your intentions when making the changes and if the replication steps is correct? Your commits helped a lot in drilling down the issue but I'm not familiar with React internals, so don't want to explain or assume the wrong things.

@gaearon
Copy link
Member

@gaearon gaearon commented Jun 9, 2021

@julianfssen, massive thanks for getting to the bottom of this.

@gaearon
Copy link
Member

@gaearon gaearon commented Jun 9, 2021

We're a bit overloaded with other things right now so I don't know if we'll take a detailed look very soon. You already gathered a lot of context for this issue — do you have a proposed fix in mind?

@acdlite
Copy link
Member

@acdlite acdlite commented Jun 9, 2021

@julianfssen Thanks for the detailed write up!

So based on your description, Firefox has a bug where alert and debugger will pause the current event but will still spin the event loop to fire the next pending event, including message events which React uses to flush scheduled work. Then React throws an error because it detects that the previous render (the one with the debugger) hasn't finished yet.

My guess for why supportsMicrotask "fixes" the issue is that microtasks are part of the current event, so the debugger actually does block those from firing.

Perhaps there is a way we could detect this scenario in development and fail more gracefully. I'm loath to add more code to the production build to address something that is ultimately a Firefox bug, and one that only happens during development (unless you use an alert in prod, I guess, but that's not that common).

@alexandcote
Copy link

@alexandcote alexandcote commented Jun 9, 2021

I would be curious to know if the prompt triggered by beforeunload causes the same issue because we don't use alert in production but we see some occurrence of this error. Can also be confirm which is probably similar.

@gaearon
Copy link
Member

@gaearon gaearon commented Jun 9, 2021

Yea that's the one that got me worried. Confirm is pretty common for "do you want to stay on this page?" flows.

@acdlite
Copy link
Member

@acdlite acdlite commented Jun 9, 2021

Right, prompt seems legit.

So the fix for this would be pretty simple, I think — instead of throwing an error, we'd exit from the function. I think this would work because when the paused event continues and eventually finishes, it will re-schedule a new render to replace the one that we exited from.

But this is a bit fragile, and I'd rather not commit to supporting this workaround long term. Hopefully we can convince the Firefox team to fix the underlying issue.

@julianfssen
Copy link

@julianfssen julianfssen commented Jun 10, 2021

@acdlite thanks for explanation! That makes sense, and I agree that altering logic to cater for a specific browser bug does not seem 'right'. However, the event loop bug in Firefox has been there for over a decade now so I'm not sure if it's going to be fixed anytime soon. Based on my tests, the microtasks implementation works correctly for the behavior above. Since most modern browsers support microtasks, perhaps this is 'fixed' if the implementation goes in the next release?

@alexandcote thanks for pointing that out, I forgot about confirm and prompt when testing. I believe the issue happens in Firefox if the modal is meant to pause execution, so prompt and confirm will likely trigger the same issue since it (should?) works similarly to alert. I can test it this weekend.

@gaearon thanks! I'd love to suggest a fix but my knowledge of React internals is not good at the moment. I'll have a look again and tinker around with the implementation this weekend based on @acdlite 's feedback. That said, if anyone wants to take over this issue, go ahead! The issue relates to WebSockets not pausing on calls that are supposed to block execution (e.g. alert, debugger, confirm, etc.) but there may be more to discover about it.

@joshunger
Copy link

@joshunger joshunger commented Jun 30, 2021

We just ran across this in our Bugsnag logs this morning but it was ONLY for Chrome 83.0.4103 just like @mooflu. Maybe there is a bug in Chrome 83.0.4103 as well?

It might be related to this code -

  const [ready, toggleReady] = useState(false);
  useEffect(() => {
    if (branchKey && window.branch) {
      try {
        window.branch.init(branchKey, branchError => {
          if (!branchError) {
            toggleReady(true);
          }
        });
      } catch (branchError) {
        logError(branchError);
      }
    }
  }, [branchKey]);
@syntithenai
Copy link

@syntithenai syntithenai commented Jul 1, 2021

Same error "Should not already be working" in Firefox but not Brave/Chrome (on Linux).
Problem code was trying to open a window (for polling login) in componentDidMount.

Problem goes away when I wrap the call in setTimeout.

setTimeout(function() {
				that.createLoginIframe()
			}, 1000)
@lebchen
Copy link

@lebchen lebchen commented Nov 22, 2021

I am getting the same behaviour in Firefox, when React is rendering components from within an IntersectionObserver and rendering components from outside of the same IntersectionObserver at the same time. Using window.setTimeout(renderCall, 0) from within the IntersectionObserver solves the issue.

I also noticed this is only happening, if the component NOT rendered through IntersectionObserver is making a synchronous network call! I managed to duplicate the issue here:

https://codesandbox.io/s/should-not-already-be-working-x1syi?file=/src/App.js

I am guessing this observed behaviour in Firefox is related to the discussions in here.

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