facebook/react · error · Error

Unable to find node on an unmounted component.

Error message

Unable to find node on an unmounted component.

What it means

assertIsMounted is an internal guard used when React reflects over the fiber tree (findCurrentFiberUsingSlowPath and its callers, e.g. findDOMNode-style and findCurrentHostFiber lookups). It requires that the fiber being inspected is itself its nearest mounted fiber, i.e. it is still attached to a mounted HostRoot. Accessing a component or instance whose tree has unmounted makes this invariant fail and React throws rather than return a node from a dead tree.

Source

Thrown at packages/react-reconciler/src/ReactFiberTreeReflection.js:113

      }
    }
    if (activityState !== null) {
      return activityState.dehydrated;
    }
  }
  // TODO: Implement this on ActivityComponent.
  return null;
}

export function getContainerFromFiber(fiber: Fiber): null | Container {
  return fiber.tag === HostRoot
    ? (fiber.stateNode.containerInfo as Container)
    : null;
}

function assertIsMounted(fiber: Fiber) {
  if (getNearestMountedFiber(fiber) !== fiber) {
    throw new Error('Unable to find node on an unmounted component.');
  }
}

export function findCurrentFiberUsingSlowPath(fiber: Fiber): Fiber | null {
  const alternate = fiber.alternate;
  if (!alternate) {
    // If there is no alternate, then we only need to check if it is mounted.
    const nearestMounted = getNearestMountedFiber(fiber);

    if (nearestMounted === null) {
      throw new Error('Unable to find node on an unmounted component.');
    }

    if (nearestMounted !== fiber) {
      return null;
    }
    return fiber;
  }

View on GitHub (pinned to eafeac097b)

Solutions

  1. Null-check and connectivity-check the ref/instance (ref.current != null && ref.current.isConnected) before touching it
  2. Cancel timers, observers, and event listeners in the useEffect cleanup function so callbacks never run after unmount
  3. Move the read into useEffect/useLayoutEffect scoped to the same component so it runs only while mounted
  4. Verify only one copy/version pair of react and react-dom is loaded (npm ls react react-dom), and upgrade together — some assertIsMounted failures were fixed reconciler bugs

Example fix

// before
useEffect(() => {
  const t = setTimeout(() => measure(ref.current.getBoundingClientRect()), 100);
}, []); // no cleanup; ref.current may be null after unmount

// after
useEffect(() => {
  const t = setTimeout(() => {
    const node = ref.current;
    if (node != null && node.isConnected) {
      measure(node.getBoundingClientRect());
    }
  }, 100);
  return () => clearTimeout(t);
}, []);
Defensive patterns

Strategy: validation

Validate before calling

function isStillMounted(node) {
  return node != null && node.isConnected === true;
}
// before any imperative lookup
if (isStillMounted(ref.current)) {
  const dom = findDOMNodeEquivalent(ref.current);
}

Type guard

function isAttachedElement(node) {
  return node instanceof Element && node.isConnected;
}

Prevention

When it happens

Trigger: Calling a reflection API (findDOMNode, findCurrentHostFiber, container lookups built on findCurrentFiberUsingSlowPath) on a fiber whose nearest mounted ancestor is a different fiber — the referenced component unmounted and the fiber is detached from any mounted tree.

Common situations: setTimeout/requestAnimationFrame/event callbacks that fire after the component unmounted and still read a DOM node or instance; StrictMode double-mount tests holding fibers from the first pass; Fast Refresh/hot reload keeping stale references; duplicate react + react-dom copies disagreeing about mount state during partial upgrades.

Related errors


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