{"record":{"id":"6b76af3f47656366","repo":"facebook/react","slug":"488","errorCode":"488","errorMessage":"Couldn't find all resumable slots by key/index during replaying. The tree doesn't match so React will fallback to client rendering.","messagePattern":"Couldn't find all resumable slots by key/index during replaying\\. The tree doesn't match so React will fallback to client rendering\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"packages/react-server/src/ReactFizzServer.js","lineNumber":1837,"sourceCode":"  // We can reuse the current context and task to render the content immediately without\n  // context switching. We just need to temporarily switch which boundary and replay node\n  // we're writing to. If something suspends, it'll spawn new suspended task with that context.\n  task.blockedBoundary = resumedBoundary;\n  task.hoistableState = resumedBoundary.contentState;\n  task.keyPath = keyPath;\n  task.formatContext = getSuspenseContentFormatContext(\n    request.resumableState,\n    prevContext,\n  );\n  task.row = null;\n  task.replay = {nodes: childNodes, slots: childSlots, pendingTasks: 1};\n\n  try {\n    // We use the safe form because we don't handle suspending here. Only error handling.\n    renderNode(request, task, content, -1);\n\n    if (task.replay.pendingTasks === 1 && task.replay.nodes.length > 0) {\n      throw new Error(\n        \"Couldn't find all resumable slots by key/index during replaying. \" +\n          \"The tree doesn't match so React will fallback to client rendering.\",\n      );\n    }\n    task.replay.pendingTasks--;\n    if (\n      resumedBoundary.pendingTasks === 0 &&\n      resumedBoundary.status === PENDING\n    ) {\n      // This must have been the last segment we were waiting on. This boundary is now complete.\n      // Therefore we won't need the fallback. We early return so that we don't have to create\n      // the fallback.\n      resumedBoundary.status = COMPLETED;\n      request.completedBoundaries.push(resumedBoundary);\n      // We restore the parent componentStack. Semantically this is the same as\n      // popComponentStack(task) but we do this instead because it should be slightly\n      // faster\n      return;","sourceCodeStart":1819,"sourceCodeEnd":1855,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server/src/ReactFizzServer.js#L1819-L1855","documentation":"When prerendered SSR output is resumed, React walks recorded replay 'slots' keyed by type and key/index. In replaySuspenseBoundary the server replays a previously postponed Suspense boundary's content; if the replay pass finishes while pendingTasks is still 1 and replay nodes remain, some recorded slots were never matched. React throws error code 488 so the boundary falls back to client rendering instead of emitting a mismatched tree.","triggerScenarios":"Resuming a postponed Suspense boundary whose children render differently than during prerender: different keys, reordered siblings, flipped conditionals, or environment-dependent output between the two passes.","commonSituations":"Prerendering at build time and resuming in a runtime with different env vars, feature flags, locale, timezone, or random/time-based output; a stale prerendered payload deployed with newer app code.","solutions":["Make the resumed render produce the identical tree: same keys, same order, same conditionals as the prerender pass","Move nondeterministic or environment-dependent output behind boundaries that stay postponed, or gate it to the client","Regenerate the prerendered payload with the same code and config as the resume runtime","Accept the fallback: ensure a hydration-capable client bundle exists so React can client-render the mismatched boundary"],"exampleFix":"// before\n{items.map((item) => <Row key={Math.random()} item={item} />)}\n// keys differ between prerender and resume -> slots never matched\n\n// after\n{items.map((item) => <Row key={item.id} item={item} />)}\n// stable keys match the recorded slots on resume","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"// Do not try/catch: React converts this error into a client-render fallback for the boundary.\n// Observe it through the error hooks of your render/resume API instead:\n//   onError(err) { log.warn('resume mismatch -> client rendering fallback:', err.message); }","preventionTips":["Use stable keys and deterministic ordering in anything that resumes","Run prerender and resume with identical env vars, flags, and code versions","Keep Date.now()/Math.random()/locale-dependent output out of resumed trees"],"tags":["ssr","resume","prerender","tree-mismatch","suspense"],"backgroundTag":"ssr-resume-tree-mismatch","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}