Skip to content

refactor: force infinite render loop detection to throw instead of wa…#36531

Open
dev-himanshu-x wants to merge 1 commit into
facebook:mainfrom
dev-himanshu-x:infinite-loop-render-useeffect
Open

refactor: force infinite render loop detection to throw instead of wa…#36531
dev-himanshu-x wants to merge 1 commit into
facebook:mainfrom
dev-himanshu-x:infinite-loop-render-useeffect

Conversation

@dev-himanshu-x
Copy link
Copy Markdown

@dev-himanshu-x dev-himanshu-x commented May 24, 2026

…rning and remove related feature flags

Summary

This PR addresses the asymmetric behavior between synchronous and passive infinite render loop detection (originally raised in #36423). Currently, the NESTED_PASSIVE_UPDATE_LIMIT guard for useEffect loops is completely wrapped inside if (__DEV__), causing infinite render loops to fail silently and freeze browser tabs in production environments.

This change:

  1. Promotes the NESTED_PASSIVE_UPDATE_LIMIT check out of the __DEV__ guard block so it is included in production builds.
  2. Changes the behavior from a soft console.error to an explicit throw new Error(...) across both development and production. This ensures that useEffect infinite loops correctly trigger Error Boundaries, root uncaught error options, and telemetry monitoring tools (such as Sentry or Datadog).
  3. Refactors and completely cleans up the older experimental enableInfiniteRenderLoopDetection feature flags and instrumentations that were falling back to casual console warnings, reducing dead code pathways in ReactFiberWorkLoop.js.

Fixes #36423

How did you test this change?

  1. Unit Tests: Ran the internal React test suite using yarn test to verify that no core reconciler behaviors were broken.
  2. Production Builds: Ran yarn test --prod and built the standalone production bundles via yarn build react/index,react-dom/index --type=NODE to guarantee the check compiles successfully without __DEV__.
  3. Manual Verification: Verified against a local reproduction app running a headless build of React with an un-depped useEffect setting state. The production build now safely crashes the breaking tree and surfaces a catchable error stack trace immediately instead of freezing the single thread.

Copilot AI review requested due to automatic review settings May 24, 2026 11:07
@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented May 24, 2026

Hi @dev-himanshu-x!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@meta.com. Thanks!

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@meta-cla
Copy link
Copy Markdown

meta-cla Bot commented May 24, 2026

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

@meta-cla meta-cla Bot added the CLA Signed label May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: useEffect infinite loops are silent in production - NESTED_PASSIVE_UPDATE_LIMIT check is __DEV__-only and never throws

2 participants