[PPF] Fix missing runtime-follow up if hints are stale by lubieowoce · Pull Request #98278 · vercel/next.js · GitHub
Skip to content

[PPF] Fix missing runtime-follow up if hints are stale - #98278

Draft
lubieowoce wants to merge 1 commit into
canaryfrom
lubieowoce/fix-runtime-followup
Draft

[PPF] Fix missing runtime-follow up if hints are stale#98278
lubieowoce wants to merge 1 commit into
canaryfrom
lubieowoce/fix-runtime-followup

Conversation

@lubieowoce

Copy link
Copy Markdown
Member

if a page didn't use runtime data during build but started doing so after the revalidation (i.e. the hints say its statically-prefetchable but now it's not), we're supposed to be doing a follow-up runtime request based on the needsRuntimeRequest promise, but this was not actually happening.

the bug goes as follows:

  1. if we get an entry from a static prefetch, but needsRuntimeRequest is true, we save it as PPR (or StaticShell if it's a shell rewound from the static response). otherwise, we'd have saved it as PPRRuntime (or RuntimeShell for shells) to indicate that it satisfies those requests.
  2. wouldRuntimeRequestProvideMore compares the runtime strategy for the current static walk to the entry's strategy to check if it should do a runtime request. this boils down to a comparison of RuntimeShell > PPR for a shell request
  3. however, in the FetchStrategy enum, RuntimeShell = 3 and PPR = 3, so RuntimeShell > PPR is false, which makes wouldRuntimeRequestProvideMore return false. so, if we have a PPR entry, we'll never do a follow-up runtime shell request.

this is fixed by swapping the two values in the enum.
this is a bit of a lie, because there is no single correct ordering -- a PPR entry might actually provide more content than a ShellRuntime entry if the route uses static params.
however, if we end up with PPR but its needsRuntimeRequest was true due to runtime data, that indicates that we should've done a runtime request in the first place, we just didn't know we should do so because the prefetch hint was stale, so the new ordering achieves the correct behavior in this case.

Edge cases

there is one (somewhat involved) edge case to this that i know of.
if the post-revalidation static response has:

  1. a shell that didn't access runtime data (i.e. needsRuntimeRequest = false in the shell stage)
  2. a prefetch that did access runtime data (i.e. needsRuntimeRequest = true in the static stage)

then we'll:

  1. write the shell as ShellRuntime (because needsRuntimeRequest = false, and a runtime shell would not in fact provide more data)
  2. write the prefetch as PPR (and not PPRRuntime, because needsRuntimeRequest = true, and a runtime prefetch would provide more data)

with the new ordering, this means we'll end up preferring the ShellRuntime entry over the PPR entry even though the shell is a strict subset of it and would be missing static params and content gated behind prefetch() or navigation().

this can be observed as follows:

  1. when a <Link prefetch={true}> to such a page is revealed, we won't request a runtime shell (due to already having a ShellRuntime entry), but we will request a runtime prefetch (because PPR is not enough). so far this is correct
  2. if the navigation happens before this runtime prefetch completes, we will display what we have. but we'll prefer the rewound ShellRuntime shell entry over than the PPR entry it originated from because of the enum ordering. so we may end up not showing content despite having it in the cache

i'm not sure how to resolve this yet, but i think the current recordedFetchStrategy trick can't handle this, and we need a more involved mechanism that can detect when the PPR entry is actually better. i don't consider this a blocker for this fix though


Stack created with GitHub Stacks CLIGive Feedback 💬

@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

@lubieowoce
lubieowoce force-pushed the lubieowoce/fix-runtime-followup branch from 6779b37 to f31bfbe Compare September 4, 2026 22:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant