mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
When a `"use cache"` function receives arguments that differ between the cache warming phase and the final prerender, the cache key changes and the Resume Data Cache (RDC) entry from the prospective prerender is missed. This can happen for various reasons, for example when concurrent async operations push results into a shared array in non-deterministic order, and that array is then passed as an argument to a cached function. Without a `cacheSignal` to keep the render alive, the final prerender aborts the cache entry generation, producing an incomplete RSC stream that causes "Connection closed" errors. This change detects that scenario (an RDC miss during the final prerender where `cacheSignal` is `null`) and returns a hanging promise instead of generating a broken cache entry. A warning is logged to help developers identify the non-deterministic arguments. By making the cached function a dynamic hole rather than erroring, the prerender can still complete and produce at least a partial shell if there is a Suspense boundary above. This affects both on-demand prerendering and runtime prefetching. To avoid false positives, cache keys that were intentionally skipped during the prospective prerender (e.g. because the cached function accessed fallback params) are tracked in a `dynamicCacheKeys` set on the RDC. During the final prerender, a known dynamic key is returned as a hanging promise early without logging a warning. This also serves as a performance optimization, since it avoids trying to regenerate the entry. This set is intentionally not serialized, as cache misses for dynamic keys should generate fresh entries during the resume at request time.
15 KiB
15 KiB