Skip to content

[pull] canary from vercel:canary#796

Merged
pull[bot] merged 8 commits intocode:canaryfrom
vercel:canary
Feb 17, 2026
Merged

[pull] canary from vercel:canary#796
pull[bot] merged 8 commits intocode:canaryfrom
vercel:canary

Conversation

@pull
Copy link

@pull pull bot commented Feb 17, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

nextjs-bot and others added 8 commits February 16, 2026 23:26
When a route has `unstable_instant` defined on any segment, setting
`prefetch={true}` on a Link to that route is now a no-op. The prefetch
behaves the same as the default auto strategy — cached content is
prefetched but dynamic content is deferred to navigation time.

A full static prefetch doesn't make sense for routes with instant
configs, since those segments use runtime prefetching. Rather than
silently doing something the developer didn't intend, we ignore the prop
entirely.

To detect this on the client, the server now sends a bitmask instead of
a boolean for the per-segment prefetch metadata. One bit tracks whether
the subtree contains any instant config, which propagates up so the
client can check it at the root without traversing.
This aims to avoid us having tests stall for upwards of 240s when a
single assertion in the test stalls. This is very common currently. To
also avoid wasting the entire time of resetting the test suite this also
allows 1 retry for individual failed assertions. This won't always work
since some assertions rely on previous setup so this also keeps the
entire test suite retry handling as a fallback.

This change is not applied for dev tests as they check HMR and compile
lazily.

## Summary
- keep elevated Jest timeout for test setup/startup in e2e-utils
- enforce a 60s default timeout for individual `it`/`test` cases
- apply one retry per individual test via `jest.retryTimes(1)`

## Verification
- pnpm testonly test/development/gssp-notfound/index.test.ts
- pnpm testonly test/development/enoent-during-require/index.test.ts
- pnpm testonly test/e2e/custom-app-render/custom-app-render.test.ts

Tested against our deploy tests to see if this helps:

Current run
[21967823508](https://github.com/vercel/next.js/actions/runs/21967823508)

Jobs: 24 (with test-runner output: 20)
Whole-suite retry starts: 11 (retry 1: 8, retry 2+: 3)
Jobs that needed suite retries: 8
Unique test files retried: 7

Previous run
[21964085768](https://github.com/vercel/next.js/actions/runs/21964085768)

Jobs: 26 (with test-runner output: 20)
Whole-suite retry starts: 18 (retry 1: 13, retry 2+: 5)
Jobs that needed suite retries: 9
Unique test files retried: 12
## Summary
Reworks Turbopack deferred entries in production build so deferred
routes are processed last in the same project lifecycle, with
`onBeforeDeferredEntries` executed between the non-deferred and deferred
phases.

## What changed
- Moved deferred build phasing into Rust in
`project_write_all_entrypoints_to_disk`:
  - non-deferred phase
  - `onBeforeDeferredEntries`
  - deferred phase
- Kept callback invocation on the Rust side via the existing node-worker
callback plumbing.
- Narrowed invalidation after `onBeforeDeferredEntries` to deferred app
source subtrees instead of invalidating the whole project filesystem
cache.
- Added `DiskFileSystem::invalidate_path_and_children_with_reason(...)`
in `turbo-tasks-fs`.
- Derived deferred invalidation dirs from deferred routes’
`original_name` values.
- Retained a full-invalidation fallback only when app-dir path
resolution is unavailable.
- Deferred route selection still includes both app pages and app route
handlers.

## Validation
- `cargo check -p next-napi-bindings -p turbo-tasks-fs`
- `pnpm test-start-turbo
test/e2e/deferred-entries/deferred-entries.test.ts` (21/21 passing)
- Validated against [workflows
repo](vercel/workflow#1058) and v0
This ensures we always set this env variable so that it overrides any
flag opt ins when we specifically want to test with or without the
adapter.
Stacked on #89971

This controller was introduced to help with dev time validation. It
models stage transitions in a helpful way that will become more useful
soon as we get more advanced with what kinds of sync IO are considered
errors.

To prepare for this we will update the implementation to use the stage
controller for build and runtime prerendering not just dev

We don't yet use it for static prerendering because that one is so
simple and there is really no stage beyond the first one and then an
abort so we will keep it as is

Additionally, the private cache store no longer has the
`runtimeStagePromise`. when you first enter this store type during a
runtime prerender we wait until the outer store's runtime stage has
begun. Previously the proimse signifying this stage transition was
included in the private cache store itself so nested caches could
similarly wait, however you can't actually get to a nested cache until
after it is resolved b/c the outermost one blocks.
Stacked on #89972

The pipelining function has some awkward structure. This change cleans
up the structure a bit

Notably there is a potentially meaningful change here where the final
user provided task in runInSequentialTasks gets the same Fast Immediate
treatment as the other tasks do. There is an implicit final task which
does the assertion that there are no remaining immediates unflushed and
then resolves the original tasks value.
@pull pull bot locked and limited conversation to collaborators Feb 17, 2026
@pull pull bot added the ⤵️ pull label Feb 17, 2026
@pull pull bot merged commit 6df47fc into code:canary Feb 17, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

Comments