question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Errors thrown in useEffect cleanup functions result in `Internal React error`

See original GitHub issue

Description

When an app includes a functional component which calls React.useEffect with a cleanup callback, and that callback throws an error when called, the following is produced in the console:

ERROR  Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.

The error is not detectable otherwise: the error boundary component does not catch it, nor does installing a global handler with ErrorUtils.setGlobalHandler().

This is on React Native 0.66.3 and React 17.0.2. I’ve also checked React 17.0.1 (no difference in behaviour), and RN 0.65.0 (the one that we currently use in production) which also gobbles up the error, but silently, without producing any message in the console.

The app seemingly continues to work after the error occurs.

I don’t think this is an actual React bug (as opposed to React Native), because on web, the error appears in the browser console, as expected.

I checked only the debug build behaviour, not the release one. It may be the case that in release builds the error sometimes does bubble up to the global error handler (if set), because we’re seeing prod exceptions that are likely to be related to this issue. For the record, what causes this for us is this issue in react-navigation, exacerbated by the fact that they had moved removing listeners to a useEffects cleanup function.

Version

0.66.3

Output of react-native info

System:
    OS: macOS 11.4
    CPU: (6) x64 Intel(R) Core(TM) i5-8500B CPU @ 3.00GHz
    Memory: 1.97 GB / 32.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 15.3.0 - ~/.nvm/versions/node/v15.3.0/bin/node
    Yarn: 1.22.15 - /usr/local/bin/yarn
    npm: 7.0.14 - ~/.nvm/versions/node/v15.3.0/bin/npm
    Watchman: 2021.10.04.00 - /usr/local/bin/watchman
  Managers:
    CocoaPods: 1.11.2 - /Users/nathell/.gem/bin/pod
  SDKs:
    iOS SDK:
      Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4
    Android SDK: Not Found
  IDEs:
    Android Studio: 3.6 AI-192.7142.36.36.6392135
    Xcode: 12.5/12E262 - /usr/bin/xcodebuild
  Languages:
    Java: 11.0.7 - /usr/bin/javac
  npmPackages:
    @react-native-community/cli: Not Found
    react: 17.0.2 => 17.0.2 
    react-native: 0.66.3 => 0.66.3 
    react-native-macos: Not Found
  npmGlobalPackages:
    *react-native*: Not Found

Steps to reproduce

  1. Create a RN app with react-native init myapp.

  2. Edit App.js to read:

import React from 'react';
import { Text, TouchableOpacity, View, SafeAreaView } from 'react-native';

const Hello = () => {
  React.useEffect(() => {
    console.log("mount");
    return () => {
      console.log("cleanup");
      throw new Error("KABOOM!");
      console.log("cleanup 2");
    };
  }, []);
  return <Text>Hello!</Text>;
}

const App = () => {
  const [shown, show] = React.useState(false);
  const onPress = () => show(!shown);

  return (
    <SafeAreaView>
      { shown ? <Hello /> : null }
      <TouchableOpacity onPress={onPress}>
        <Text>Touch me</Text>
      </TouchableOpacity>
    </SafeAreaView>
  );
};

export default App;
  1. Run the resulting app (on either iOS or Android) and tap Touch me twice.

Expected result (in the react-native start output):

 LOG  mount
 LOG  cleanup
 ERROR  Kaboom!

Actual result:

 LOG  mount
 LOG  cleanup
 ERROR  Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.

Snack, code example, screenshot, or link to a repository

No response

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:5
  • Comments:19

github_iconTop GitHub Comments

3reactions
walid-moscommented, Oct 3, 2022

I got roughly the same issue here, with react base

Error Stack : 
Warning: Internal React error: Attempted to capture a commit phase error inside a detached tree. This indicates a bug in React. Likely causes include deleting the same fiber more than once, committing an already-finished tree, or an inconsistent return pointer.

Error message:

TypeError: undefined is not a function
    in HybridProvider (created by NativeBaseProvider)
    in ResponsiveQueryProvider (created by NativeBaseProvider)
    in RNCSafeAreaProvider (created by SafeAreaProvider)
    in SafeAreaProvider (created by NativeBaseProvider)
    in NativeBaseConfigProviderProvider (created by NativeBaseProvider)
    in NativeBaseProvider (created by App)
    in Provider (created by App)
    in App
1reaction
Tran281commented, Oct 17, 2022

Check if any async is used inside useEffect hook and remove it. Worked for me

Read more comments on GitHub >

github_iconTop Results From Across the Web

Understanding React's useEffect cleanup function
React's useEffect cleanup function saves applications from unwanted behaviors like memory leaks by cleaning up effects.
Read more >
Getting error after I put Async function in useEffect
One feature of the useEffect hook is a cleanup function. If you return anything from the useEffect hook function, it must be a...
Read more >
Suspense for Data Fetching (Experimental) - React
This problem is possible to fix (you could use the effect cleanup function to either ignore or cancel stale requests), but it's unintuitive...
Read more >
Cleaning up Async Functions in React's useEffect Hook ...
Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application....
Read more >
React error boundaries with useEffect and async function ...
Event handlers (learn more) · Asynchronous code (e.g. setTimeout or requestAnimationFrame callbacks) · Server side rendering · Errors thrown in the error boundary ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found