@@ -50,6 +50,7 @@ import {
5050} from '../../shared/lib/hooks-client-context.shared-runtime'
5151import { getParamValueFromCacheKey } from '../route-params'
5252import type { Params } from '../../server/request/params'
53+ import { isDeferredRsc } from './router-reducer/ppr-navigations'
5354
5455/**
5556 * Add refetch marker to router state at the point of the current layout segment.
@@ -375,11 +376,27 @@ function InnerLayoutRouter({
375376 // special case `null` to represent that this segment's data is missing. If
376377 // it's a promise, we need to unwrap it so we can determine whether or not the
377378 // data is missing.
378- const resolvedRsc : React . ReactNode =
379- typeof rsc === 'object' && rsc !== null && typeof rsc . then === 'function'
380- ? use ( rsc )
381- : rsc
379+ let resolvedRsc : React . ReactNode
380+ if ( isDeferredRsc ( rsc ) ) {
381+ const unwrappedRsc = use ( rsc )
382+ if ( unwrappedRsc === null ) {
383+ // If the promise was resolved to `null`, it means the data for this
384+ // segment was not returned by the server. Suspend indefinitely. When this
385+ // happens, the router is responsible for triggering a new state update to
386+ // un-suspend this segment.
387+ use ( unresolvedThenable ) as never
388+ }
389+ resolvedRsc = unwrappedRsc
390+ } else {
391+ // This is not a deferred RSC promise. Don't need to unwrap it.
392+ resolvedRsc = rsc
393+ }
382394
395+ // TODO: At this point, the only reason `resolvedRsc` would be null is if the
396+ // data for this segment was fetched by a reducer that hasn't been migrated
397+ // yet to the Segment Cache implementation. It shouldn't happen for regular
398+ // navigations. Once we convert the remaining reducers, we can delete the
399+ // lazy fetching block below.
383400 if ( ! resolvedRsc ) {
384401 // The data for this segment is not available, and there's no pending
385402 // navigation that will be able to fulfill it. We need to fetch more from
@@ -418,6 +435,7 @@ function InnerLayoutRouter({
418435 previousTree : fullTree ,
419436 serverResponse,
420437 navigatedAt,
438+ retry : null ,
421439 } )
422440 } )
423441
@@ -610,6 +628,14 @@ export default function OuterLayoutRouter({
610628 // (This only applies to page segments; layout segments cannot access search
611629 // params on the server.)
612630 const activeTree = parentTree [ 1 ] [ parallelRouterKey ]
631+ if ( activeTree === undefined ) {
632+ // Could not find a matching segment. The client tree is inconsistent with
633+ // the server tree. Suspend indefinitely; the router will have already
634+ // detected the inconsistency when handling the server response, and
635+ // triggered a refresh of the page to recover.
636+ use ( unresolvedThenable ) as never
637+ }
638+
613639 const activeSegment = activeTree [ 0 ]
614640 const activeStateKey = createRouterCacheKey ( activeSegment , true ) // no search params
615641
0 commit comments