facebook/react · error

331

331

Error message

Cannot flush passive effects while already rendering.

What it means

flushPassiveEffects must run outside render and commit: it can itself perform work and re-enter the scheduler. The guard asserts executionContext has neither RenderContext nor CommitContext when passive effects flush (error code 331); a violation means passive effects were flushed synchronously from inside a render or commit phase — a reconciler re-entrancy invariant.

Source

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

  const root = pendingEffectsRoot;
  const lanes = pendingEffectsLanes;
  pendingEffectsStatus = NO_PENDING_EFFECTS;
  pendingEffectsRoot = null as any; // Clear for GC purposes.
  pendingFinishedWork = null as any; // Clear for GC purposes.
  // TODO: This is sometimes out of sync with pendingEffectsRoot.
  // Figure out why and fix it. It's not causing any known issues (probably
  // because it's only used for profiling), but it's a refactor hazard.
  pendingEffectsLanes = NoLanes;

  if (enableYieldingBeforePassive) {
    // We've finished our work for this render pass.
    root.callbackNode = null;
    root.callbackPriority = NoLane;
  }

  if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
    throw new Error('Cannot flush passive effects while already rendering.');
  }

  if (enableProfilerTimer && enableComponentPerformanceTrack) {
    // We're about to log a lot of profiling for this commit.
    // We set this once so we don't have to recompute it for every log.
    setCurrentTrackFromLanes(lanes);
  }

  if (__DEV__) {
    isFlushingPassiveEffects = true;
    didScheduleUpdateDuringPassiveEffects = false;
  }

  let passiveEffectStartTime = 0;
  if (enableProfilerTimer && enableComponentPerformanceTrack) {
    resetCommitErrors();
    passiveEffectStartTime = now();
    if (pendingDelayedCommitReason === ANIMATION_STARTED_COMMIT) {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Upgrade react and react-dom in lockstep to the latest version
  2. Dedupe react/react-dom in the bundle (npm ls react react-dom)
  3. Avoid calling flushSync from effects, layout effects, or commit-phase hooks
  4. File a React issue with the stack trace if it persists on the latest stable release
Defensive patterns

Strategy: try-catch

Prevention

When it happens

Trigger: A passive-effect flush being scheduled and executed synchronously while the reconciler is inside render or commit context, e.g. via an interleaved sync update or misuse of flushSync-style APIs from commit-phase code.

Common situations: flushSync or legacy sync lifecycle paths triggering effect flushes during commit; two react-dom copies sharing one root; upstream regressions in effect scheduling (mostly fixed in current releases).

Related errors


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