facebook/react · warning

A flushSync update cancelled a View Transition because it wa

Error message

A flushSync update cancelled a View Transition because it was called while the View Transition was still preparing. To preserve the synchronous semantics, React had to skip the View Transition. If you can, try to avoid flushSync() in a scenario that's likely to interfere.

What it means

With View Transitions enabled (React's <ViewTransition> / startTransition({viewTransition: true})), a transition is 'pending' between React preparing it and the browser actually starting it. flushPendingEffects() runs on flushSync's synchronous commit path; if a flushSync arrives while a transition is still pending, React stops the transition via stopViewTransition() to avoid running a partial animation, records ABORTED_VIEW_TRANSITION_COMMIT, and — once per session, dev builds only — warns that flushSync cancelled the View Transition. The render and commit still happen; only the animation is skipped.

Source

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

let didWarnAboutInterruptedViewTransitions = false;

export function flushPendingEffectsDelayed(): boolean {
  if (pendingDelayedCommitReason === IMMEDIATE_COMMIT) {
    pendingDelayedCommitReason = DELAYED_PASSIVE_COMMIT;
  }
  return flushPendingEffects();
}

export function flushPendingEffects(): boolean {
  // Returns whether passive effects were flushed.
  if (enableViewTransition && pendingViewTransition !== null) {
    // If we forced a flush before the View Transition full started then we skip it.
    // This ensures that we're not running a partial animation.
    stopViewTransition(pendingViewTransition);
    if (__DEV__) {
      if (!didWarnAboutInterruptedViewTransitions) {
        didWarnAboutInterruptedViewTransitions = true;
        console.warn(
          'A flushSync update cancelled a View Transition because it was called ' +
            'while the View Transition was still preparing. To preserve the synchronous ' +
            'semantics, React had to skip the View Transition. If you can, try to avoid ' +
            "flushSync() in a scenario that's likely to interfere.",
        );
      }
    }
    pendingViewTransition = null;
    pendingDelayedCommitReason = ABORTED_VIEW_TRANSITION_COMMIT;
  }
  flushGestureMutations();
  flushGestureAnimations();
  flushMutationEffects();
  flushLayoutEffects();
  // Skip flushAfterMutation if we're forcing this early.
  flushSpawnedWork();
  return flushPassiveEffects();
}

View on GitHub (pinned to eafeac097b)

Solutions

  1. Remove flushSync for that update: wrap the state change in startTransition(() => setState(...)) (with the viewTransition option where applicable) so it stays concurrent.
  2. Reorder so the synchronous update commits before the transition-wrapped update is triggered, keeping them out of the same pending window.
  3. Defer genuinely-sync work (measurement) until after the transition has started — e.g. into a post-commit effect or requestAnimationFrame.
  4. If the animation is cosmetic, accept the skip — React deliberately degrades rather than run a partial transition, and the commit itself succeeds.

Example fix

// before
function onNext() {
  startTransition(() => setPage(next)); // prepares a View Transition
  flushSync(() => setHighlight(true)); // lands while pending -> transition skipped
}

// after
function onNext() {
  flushSync(() => setHighlight(true)); // sync work commits first
  startTransition(() => setPage(next)); // transition starts undisturbed
}
Defensive patterns

Strategy: fallback

Prevention

When it happens

Trigger: Calling flushSync(fn) (ReactDOM.flushSync, a discrete sync update, or third-party code that forces a sync render) after a transition-wrapped update has been prepared but before the browser transition started — e.g. flushSync inside a layout effect or event handler that lands in the pending window of a startTransition with viewTransition.

Common situations: Mixing flushSync-based DOM measurement (editors, carousels, virtualized lists) with route/page transitions built on the View Transition API; calling flushSync inside or immediately after a transition callback; UI libraries that force synchronous renders colliding with navigation transitions.

Related errors


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