Release the instant navs lock without clearing the whole cookie jar#94947
Merged
Conversation
Contributor
Stats from current PR✅ No significant changes detected📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📎 Tarball URLCommit: d1d36eb |
Contributor
Tests PassedCommit: d1d36eb |
11cffb8 to
f56e2ac
Compare
59ffcbc to
3a1f8b1
Compare
The `instant()` helper in `@next/playwright` released the navigation
lock by calling `page.context().clearCookies({ name: INSTANT_COOKIE })`.
Playwright implements a filtered `clearCookies` non-atomically: it
clears the entire cookie jar and then re-adds the cookies that don't
match the filter, briefly removing the application's own cookies too.
Because Next.js reacts to the instant cookie's deletion by immediately
re-rendering (a soft refresh or a full reload), a render whose request
raced that empty window observed none of the test's cookies, so a page
reading `cookies()` rendered as if nothing was set, for example
`testCookie: not set`. Resource contention widened the clear-then-re-add
window, which is why the instant navigation suite failed intermittently
in CI.
We now release the lock by reading the instant cookie's stored entries
(Next.js may have updated the value, e.g. from `[0]` to `[1, null]`, but
preserves the domain and path) and re-adding each with a past expiry,
which deletes only those entries and leaves every other cookie
untouched. This removes the transient empty-jar window while still
firing the CookieStore deletion event that releases the lock.
To exercise the fix under the conditions that surfaced it, we want CI's
flake-detection job to replay the instant navigation suite, which only
happens when the suite's test file changes. We trigger that by
un-skipping the `renders runtime-prefetched content instantly during
navigation` test. That test had been skipped as flaky because of a real
bug in the dev runtime-prefetch decode, which #94866 has since fixed, so
it passes reliably now and no longer needs to be skipped.
3a1f8b1 to
d1d36eb
Compare
acdlite
approved these changes
Jun 23, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The
instant()helper in@next/playwrightreleased the navigation lock by callingpage.context().clearCookies({ name: INSTANT_COOKIE }). Playwright implements a filteredclearCookiesnon-atomically: it clears the entire cookie jar and then re-adds the cookies that don't match the filter, briefly removing the application's own cookies too. Because Next.js reacts to the instant cookie's deletion by immediately re-rendering (a soft refresh or a full reload), a render whose request raced that empty window observed none of the test's cookies, so a page readingcookies()rendered as if nothing was set, for exampletestCookie: not set. Resource contention widened the clear-then-re-add window, which is why the instant navigation suite failed intermittently in CI.We now release the lock by reading the instant cookie's stored entries (Next.js may have updated the value, e.g. from
[0]to[1, null], but preserves the domain and path) and re-adding each with a past expiry, which deletes only those entries and leaves every other cookie untouched. This removes the transient empty-jar window while still firing the CookieStore deletion event that releases the lock.To exercise the fix under the conditions that surfaced it, we want CI's flake-detection job to replay the instant navigation suite, which only happens when the suite's test file changes. We trigger that by un-skipping the
renders runtime-prefetched content instantly during navigationtest. That test had been skipped as flaky because of a real bug in the dev runtime-prefetch decode, which #94866 has since fixed, so it passes reliably now and no longer needs to be skipped.