Skip to content

Fix staged fallback params in build Instant Validation #1

Open

Description

@squarepots

Build-time Instant Validation creates a synthetic RequestStore for each instant.unstable_samples entry, but that store does not receive the stagedFallbackParams for the prerender shell selected by the sample pathname.

When a sample supplies a concrete route param, validation can therefore treat it as static even when the selected shell requires it to remain staged. This is the build-validation gap originally called out in vercel#95151. vercel#98512 later established getStagedFallbackParams() as the shell-staging authority, but build Instant Validation still does not populate that state.

Fix

Use the same prerender-candidate selection rule in build validation that development already uses.

  • Extract the existing most-specific-candidate selector and share it between development and build validation.
  • Carry only the prerender metadata required for that selection: pathname, fallbackRouteParams, remainingPrerenderableParams, and throwOnEmptyStaticShell.
  • Attach the candidate list only to the export entry that owns the existing once-per-route Instant Validation pass.
  • For each validation sample, select the matching candidate, call getStagedFallbackParams(), and populate the synthetic RequestStore.stagedFallbackParams.
  • Keep the sample URL's fallbackRouteParams separate; it represents params absent from the sample, not params staged by the selected shell.

The once-per-route validation model remains valid because that single pass already iterates every configured sample; shell selection happens per sample.

Regression coverage

The existing static-prefetch params case now covers the build path. With the fix, the sampled concrete param remains staged and build validation reports the missing Suspense boundary. Removing only the new RequestStore.stagedFallbackParams assignment makes the same route false-pass.

Focused coverage also verifies the selected mask and candidate selection, including most-specific matching, stable equal-specificity ordering, novel paths, and mixed generateStaticParams shapes.

Current verification on 0f3a2bef2692e785b1d59579241a1f00df1118bc:

  • fallback-params.test.ts: 38/38 passed.
  • Fixed build proof: expected missing-Suspense validation failure, exit 1.
  • Mutation proof with the staged-mask assignment removed: false-pass, exit 0.
  • pnpm build-all: 18/18 tasks passed.
  • Type check, touched-file ESLint, Prettier, and commit hook passed.
  • No exact upstream issue or PR duplicate was found.

Canonical isolated E2E coverage remains for Linux CI. On Windows, exact --debug-build-paths selection for a path containing [param] reduces to /404; local mutation testing used the supported wildcard path app/suspense-in-root/static/missing-suspense-around-params/**/page.tsx without changing the test harness.

Upstream strategy

One focused bug-fix PR against vercel/next.js:canary.

Suggested title: Fix staged fallback params in build Instant Validation

Relevant history: vercel#95151, vercel#94595, vercel#98512, and vercel#98944.

Activity

  1. changed the title [-]Directly prove staged fallback parameter masks in build validation[/-] [+]Define staged fallback masks for build Instant Validation[/+] on Sep 21, 2026
  2. changed the title [-]Define staged fallback masks for build Instant Validation[/-] [+]Fix staged fallback params in build Instant Validation[/+] on Sep 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions