facebook/react · warning

Cannot cancel root view transition on a comment node. All vi

Error message

Cannot cancel root view transition on a comment node. All view transitions will be globally scoped.

What it means

cancelRootViewTransitionName (packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1669) removes the viewTransitionName react-dom previously set on the container's documentElement when a root's document-level view transition is cancelled. When the root container is a comment node (rendering into <!-- comment --> containers is supported via disableCommentsAsDOMContainers), there is no element to un-name, so react-dom warns and returns: document-level (globally scoped) view transitions cannot be cancelled for this root. The consequence is that any viewTransitionName set on documentElement stays, so subsequent transitions remain globally scoped.

Source

Thrown at packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js:1669

        fill: 'forwards',
        pseudoElement: '::view-transition-group(' + oldName + ')',
      },
    );
  }
}

export function cancelRootViewTransitionName(rootContainer: Container): void {
  const documentElement: null | HTMLElement =
    rootContainer.nodeType === DOCUMENT_NODE
      ? (rootContainer as any).documentElement
      : rootContainer.ownerDocument.documentElement;

  if (
    !disableCommentsAsDOMContainers &&
    rootContainer.nodeType === COMMENT_NODE
  ) {
    if (__DEV__) {
      console.warn(
        'Cannot cancel root view transition on a comment node. All view transitions will be globally scoped.',
      );
    }
    return;
  }

  if (
    documentElement !== null &&
    // $FlowFixMe[prop-missing]
    documentElement.style.viewTransitionName === ''
  ) {
    // $FlowFixMe[prop-missing]
    documentElement.style.viewTransitionName = 'none';
    documentElement.animate(
      {opacity: [0, 0], pointerEvents: ['none', 'none']},
      // $FlowFixMe[incompatible-type]
      {
        duration: 0,

View on GitHub (pinned to eafeac097b)

Solutions

  1. Mount the root into a real element (e.g. <div id="root">) instead of a comment node when you rely on document-level view transitions.
  2. If a comment container is required, manually clear documentElement.style.viewTransitionName on unmount so later transitions are not stuck globally scoped.
  3. Scope view transitions to elements inside the root rather than the document root when comment containers must be used.

Example fix

// before
const container = document.createComment('react-root');
document.body.appendChild(container);
const root = createRoot(container);

// after
const container = document.createElement('div');
document.body.appendChild(container);
const root = createRoot(container);
Defensive patterns

Strategy: validation

Validate before calling

const COMMENT_NODE = 8;
if (container.nodeType === COMMENT_NODE) {
  // document-level view transitions cannot be cancelled for this root;
  // clear the name manually on unmount
  document.documentElement.style.viewTransitionName = '';
}

Type guard

const isElementContainer = (container: Node): container is HTMLElement =>
  container.nodeType === 1; // ELEMENT_NODE, safe for root view transitions

Prevention

When it happens

Trigger: Calling createRoot/hydrateRoot with a comment node as the container (or a container that resolves to one) while using View Transitions that assign a root-level viewTransitionName, then unmounting or cancelling the transition; typically only when the disableCommentsAsDOMContainers flag is off and comment containers are in play.

Common situations: Frameworks that mount React into comment placeholders for SSR streaming boundaries; test environments using comment nodes as containers; apps experimenting with the document-level View Transition APIs on comment-mounted roots.

Related errors


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