facebook/react · warning · Error

490

490

Error message

Expected the resume to render <Suspense> in this slot but instead it rendered <${getComponentNameFromType(type) || 'Unknown'}>. The tree doesn't match so React will fallback to client rendering.

What it means

During resume, a recorded replay slot was a Suspense boundary, but the resumed render placed a component whose type is not REACT_SUSPENSE_TYPE at that position. React throws error code 490 and the boundary falls back to client rendering.

Source

Thrown at packages/react-server/src/ReactFizzServer.js:3323

        // replay nodes which might be Suspense boundaries which are able to
        // absorb the error and we can still continue with siblings.
        const thrownInfo = getThrownInfo(task.componentStack);
        erroredReplay(
          request,
          task.blockedBoundary,
          request.aborted ? request.fatalError : x,
          thrownInfo,
          childNodes,
          childSlots,
          __DEV__ ? task.debugTask : null,
        );
      }
      task.replay = replay;
    } else {
      // Let's double check that the component type matches.
      if (type !== REACT_SUSPENSE_TYPE) {
        const expectedType = 'Suspense';
        throw new Error(
          'Expected the resume to render <' +
            expectedType +
            '> in this slot but instead it rendered <' +
            (getComponentNameFromType(type) || 'Unknown') +
            '>. ' +
            "The tree doesn't match so React will fallback to client rendering.",
        );
      }
      // Matched a replayable path.
      replaySuspenseBoundary(
        request,
        task,
        keyPath,
        props,
        node[5],
        node[2],
        node[3],
        node[4] === null ? [] : node[4][2],

View on GitHub (pinned to eafeac097b)

Solutions

  1. Keep the Suspense structure identical between the prerender and resume passes
  2. Do not conditionally wrap subtrees in Suspense based on runtime state
  3. Regenerate prerendered payloads whenever the Suspense layout changes

Example fix

// before
// prerender slot: <Suspense><Row /></Suspense>
// resume slot: <Row /> (wrapper removed) -> throws

// after
// keep the boundary in both passes
return <Suspense fallback={<Skeleton />}><Row /></Suspense>;
Defensive patterns

Strategy: fallback

Try / catch

// React catches this and client-renders the boundary; no user try/catch needed.
// Log via the render/resume error hooks:
//   onError(err) { log.warn('Suspense slot mismatch -> client fallback:', err.message); }

Prevention

When it happens

Trigger: Wrapping or unwrapping a subtree in <Suspense> between prerender and resume; a code change or flag adding/removing a Suspense boundary at a recorded slot; a framework version change that alters where Suspense boundaries are injected.

Common situations: Code changes between build-time prerender and runtime resume; conditional Suspense wrappers; framework upgrades that inject Suspense boundaries differently across versions.

Related errors


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