facebook/react · error

177

177

Error message

Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.

What it means

completeRoot requires the finished work-in-progress tree to differ from root.current — committing the same fiber tree twice would corrupt the alternate double-buffering. finishedWork === root.current means the root's committed tree was handed to commit again (error code 177), typically after lanes were lost or a commit was double-entered. This is an internal invariant (the message says to file an issue), not an application error.

Source

Thrown at packages/react-reconciler/src/ReactFiberWorkLoop.js:3616

      // Stop any gestures that were committed.
      if (isGestureRender(lanes)) {
        stopCommittedGesture(root);
      }
    }
    return;
  } else {
    if (__DEV__) {
      if (lanes === NoLanes) {
        console.error(
          'finishedLanes should not be empty during a commit. This is a ' +
            'bug in React.',
        );
      }
    }
  }

  if (finishedWork === root.current) {
    throw new Error(
      'Cannot commit the same tree as before. This error is likely caused by ' +
        'a bug in React. Please file an issue.',
    );
  }

  if (root === workInProgressRoot) {
    // We can reset these now that they are finished.
    workInProgressRoot = null;
    workInProgress = null;
    workInProgressRootRenderLanes = NoLanes;
  } else {
    // This indicates that the last root we worked on is not the same one that
    // we're committing now. This most commonly happens when a suspended root
    // times out.
  }

  // workInProgressX might be overwritten, so we want
  // to store it in pendingPassiveX until they get processed

View on GitHub (pinned to eafeac097b)

Solutions

  1. Upgrade to the latest release — this invariant has had multiple fixed regressions
  2. Verify a single react-dom instance owns the root (dedupe packages, no dual bundling of the renderer)
  3. Isolate the trigger (often an update during commit or an interruption pattern) and file a React issue with the repro
Defensive patterns

Strategy: try-catch

Validate before calling

import * as React from 'react';
import * as ReactDOM from 'react-dom/client';
console.assert(React.version === ReactDOM.version, 'version mismatch');
// also assert only one copy exists at runtime:
console.assert(Object.keys(window).filter((k) => k.startsWith('__REACT_DEVTOOLS')).length <= 1);

Prevention

When it happens

Trigger: The commit path receiving a finishedWork identical to root.current — e.g. an interleaved update path that resets workInProgress to the current tree, or a double invocation of commitRoot for one finished render.

Common situations: Historically reported with interleaved mutations racing sync commits (several fixed GitHub issues); duplicated react-dom copies committing one root; canary regressions in the interleaved-update paths.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/b56029066d77a938. Report an issue: GitHub.