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
- Upgrade react and react-dom in lockstep to the latest version
- Dedupe react/react-dom in the bundle (npm ls react react-dom)
- Avoid calling flushSync from effects, layout effects, or commit-phase hooks
- File a React issue with the stack trace if it persists on the latest stable release
Defensive patterns
Strategy: try-catch
Prevention
- Do not trigger effect flushes synchronously from render or commit code
- Avoid flushSync inside passive effects
- Keep matched react/react-dom versions to share one scheduling implementation
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
- 327
- Expected to see a frame at the next depth.
- Expected root pseudo key to be known.
- Expected counter to be known.
- Expected the root instance to exist when computing a path
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/a745e3866eeb7fd4.
Report an issue: GitHub.