mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
00b29d6654
The fix implemented in #95665 (`params/searchParams` not hanging correctly in Runtime App Shells during prospective prerenders) was incomplete. We started using `makeHanging[Search]Params` in the prospective prerender (if it was an app shell and wouldn't resolve them), but not during the final prerender. This meant that, when encoding the cache key, we would only fire `dynamicAccessAbortSignal` in the prospective prerender: https://github.com/vercel/next.js/blob/090f1b72753b2d0094235d27d46ffa0da5fc7d35/packages/next/src/server/use-cache/use-cache-wrapper.ts#L2160-L2174 ...but the final prerender wasn't using `makeHanging[Search]Params`, so it would not hit this early exit. The hanging input abort signal would still correctly abort the key encoding (because it accounts for `stageController.finalStage`) so the key would still be partial, as expected. We would continue on, and attempt to look the key up in the Resume Data Cache. But the prospective prerender exited early and never put anything under that key, so we would incorrectly end up here, and log: https://github.com/vercel/next.js/blob/090f1b72753b2d0094235d27d46ffa0da5fc7d35/packages/next/src/server/use-cache/use-cache-wrapper.ts#L2730-L2734 This is fixed by consistently using `makeHanging[Search]Params` if the runtime prerender won't reach the stage where they resolve, i.e. if it's an App Shell. This means we'll trigger `dynamicAccessAbortSignal` while encoding the cache key in *both* renders, so we'll do the early exit consistently and avoid the log. (This feels a bit unsatisfying, because ideally this would all just work based on stages, which is what I idealistically thought when writing the code originally. But unfortunately our usage of `dynamicAccessAbortSignal` for `params/searchParams` requires these special cases to work consistently. Maybe this can be improved in the future.) ### Tests This scenario is covered by the existing `prefetch-runtime` tests -- i discovered the bug by running them and seeing the `Unexpected cache miss after cache warming phase` warning. We now assert that the warning is not logged. The assertion is negative and would also pass if the error message changed, so i've exported the message as a constant to ensure `use-cache-wrapper` and the tests stay in sync.