facebook/react · error · Error

Missing getServerSnapshot, which is required for server-rend

Error message

Missing getServerSnapshot, which is required for server-rendered content. Will revert to client rendering.

What it means

useSyncExternalStore requires a third argument (getServerSnapshot) whenever the component can render on the server: during SSR there is no external store to subscribe to, so React needs a deterministic value to render. When the argument is missing, Fizz throws this error and the framework falls back to client rendering (or the SSR request fails).

Source

Thrown at packages/react-server/src/ReactFizzHooks.js:628

  throw new Error(
    "A function wrapped in useEffectEvent can't be called during rendering.",
  );
}

export function useEffectEvent<Args, Return, F: (...Array<Args>) => Return>(
  callback: F,
): F {
  // $FlowFixMe[incompatible-type]
  return throwOnUseEffectEventCall;
}

function useSyncExternalStore<T>(
  subscribe: (() => void) => () => void,
  getSnapshot: () => T,
  getServerSnapshot?: () => T,
): T {
  if (getServerSnapshot === undefined) {
    throw new Error(
      'Missing getServerSnapshot, which is required for ' +
        'server-rendered content. Will revert to client rendering.',
    );
  }
  return getServerSnapshot();
}

function useDeferredValue<T>(value: T, initialValue?: T): T {
  resolveCurrentlyRenderingComponent();
  return initialValue !== undefined ? initialValue : value;
}

function unsupportedStartTransition() {
  throw new Error('startTransition cannot be called during server rendering.');
}

function useTransition(): [
  boolean,

View on GitHub (pinned to eafeac097b)

Solutions

  1. Pass the third argument with a deterministic server value: useSyncExternalStore(subscribe, getSnapshot, () => initialState)
  2. Upgrade the store library/binding to an SSR-aware version that supplies getServerSnapshot (react-redux v8+, zustand v4+)
  3. If no meaningful server value exists, render a loading shell on the server and read the store only after hydration

Example fix

// before
const width = useSyncExternalStore(subscribeWindow, () => window.innerWidth); // throws on server

// after
const width = useSyncExternalStore(
  subscribeWindow,
  () => window.innerWidth,
  () => 0 // deterministic server snapshot
);
Defensive patterns

Strategy: fallback

Validate before calling

// Wrapper that refuses the two-argument form before SSR can hit it.
function useServerSafeSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
  if (!getServerSnapshot) {
    throw new Error('getServerSnapshot is required for SSR — pass a deterministic server value');
  }
  return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
}

Prevention

When it happens

Trigger: useSyncExternalStore(subscribe, getSnapshot) — two arguments — inside any component that gets server-rendered; older store bindings (zustand/redux/jotai) that do not forward a server snapshot internally; components reading window/document/location-derived stores during SSR.

Common situations: React 18 upgrades surfacing store code that never SSR'd before; third-party hooks calling useSyncExternalStore without the third argument; components using browser-only external state rendered in a server component tree.

Related errors


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