### What?
Stabilizes the pages-router `syntax > runtime error` acceptance test
without weakening its redbox assertions.
### Why?
The fixture emitted runtime errors every second and waited exactly one
second before capturing the first redbox. On slower release runners, a
second error could arrive while the asynchronous snapshot was being
collected, changing the expected single error into an array and causing
repeated retries.
The broader canary assertion cluster has several independent signatures;
this PR intentionally addresses only the timing race with a
reproducible, test-local cause.
### How?
The redbox matcher now performs the initial wait itself, while the
fixture uses a longer interval to leave a stable capture window. The
later wait remains long enough for another runtime error to occur,
preserving the test’s core assertion that a subsequent runtime error
does not replace the syntax/build error.
### Verification
- `pnpm build-all`
- `HEADLESS=true NEXT_TELEMETRY_DISABLED=1 NEXT_TEST_CI=true pnpm
test-dev-webpack test/development/acceptance/error-recovery.test.ts` (6
tests and 10 snapshots passed)
- Prettier and ESLint on the changed file
<!-- NEXT_JS_LLM -->
<!-- fleet ee9dd3ec-a271-4d0d-8165-d7872e226a6a -->
Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com>
Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
Test fixtures that depend on monorepo packages (for example
`@next/third-parties` and `@next/mdx`) declared them at the `canary`
dist-tag, which installs the published npm canary instead of the build
under test. In deploy tests this also broke the remote install entirely:
the published canary's `peerDependencies` ranges (for example
`^16.0.0-beta.0`) reject the prerelease preview versions that
`NEXT_TEST_VERSION` installs for `next` (for example
`16.4.0-preview-<sha>-<date>`), so `npm install` failed with ERESOLVE.
Test dependencies can now be declared as `workspace:*`, which resolves
to the build from the current checkout in every test mode:
- dev/start: the locally packed tarball from `pack-for-isolated-tests`,
with a descriptive error when the package has no pack task or is not
part of the repository.
- deploy: the preview tarball of the tested commit when
`NEXT_TEST_VERSION` points at a preview build (preview tarballs already
rewrite their monorepo peer dependencies to the same preview URLs, so
peer resolution succeeds), falling back to the version in the worktree
otherwise. Private packages without published preview tarballs fail with
a descriptive error.
All existing tests that used `canary` for monorepo packages are migrated
to `workspace:*`.
### Why?
Should come up with better solution that does not block PRs with git
conflict
x-ref:
https://vercel.slack.com/archives/C02CDC2ALJH/p1785263902728189?thread_ts=1785263687.502649&cid=C02CDC2ALJH
### How?
- Delete `errors.json`, the error-code SWC plugin, generated WASM, merge
driver, and validation/build tooling.
- Stop attaching error codes to server-rendering digests, redboxes, and
telemetry; native `Error.code` and `Error.name` remain available where
applicable.
- Remove the development-overlay error feedback UI, middleware, and
telemetry event that depended on stable codes.
- Update fixtures, snapshots, and guidance for code-free errors and
numeric-only digests.
<!-- NEXT_JS_LLM -->
We forked test assertions in places in the early days of merging
Turbopack. Now that we more closely align, a bunch of these had the
exact same assertions. Fold them into one.
Sorting-by-ID was flagged as bad for g-zipping:
> This sorts by chunk item id.
> Tobias has been saying that this is bad, because it gzips worse
> We should be sort by path, so that similar modules stay together. E.g.
if you have many similar icon modules
> Sorting by chunk item results in random order
Switched to sorting by path!
## Summary
- upgrade `@rspack/core` to `2.0.0-rc.0`
- sync the in-tree next rspack Rust binding/toolchain with newer rspack
releases
- align Next server runtime selection so `NEXT_RSPACK` uses the
turbo-like app runtime path
- include missing compiled `@next/react-refresh-utils` output in
`ncc-compiled`
## What is done
- `@next/rspack` Rust binding builds locally
- `packages/next` builds locally
- rspack-related tests are running and have been reduced to deeper
runtime compatibility failures
## Rspack test investigation
Latest checked CI run: `build-and-test` run `27129243230` at head
`484e7bf1b30655a9f94d0855b9e00774b4b38cd0`.
Confirmed Rspack / webpack parity gaps:
-
`test/e2e/edge-runtime-configurable-guards/edge-runtime-configurable-guards.test.ts`:
Rspack does not expose the webpack parser hooks used by
`MiddlewarePlugin`. The current Rspack path falls back to SWC analysis
in `finishModules`, which can report diagnostics but cannot apply the
parser-time transforms that wrap `eval` / `new Function`, track
`InnerGraph` usage for used vs unused dynamic code, or apply
`unstable_allowDynamic` with webpack parity. Dev therefore misses the
expected dynamic-code runtime warnings and also reports false
`process.cwd` Edge warnings from Next internals; prod fails
allowed/unused dynamic-code cases.
-
`test/development/middleware-overrides-node.js-api/middleware-overrides-node.js-api.test.ts`:
same parser-hook limitation. Webpack can observe that `process.cwd` is
overwritten before use, while the Rspack SWC fallback statically flags
`process.cwd` as an unsupported Edge Node API.
- `test/production/css-features/css-compilation.test.ts`: the CSS is
minified and prefixed as expected, but the Rspack lightningcss path
currently does not expose/control source map generation the way this
test expects, so emitted CSS has no `sourceMappingURL` comment or `.map`
file to assert.
- `test/e2e/app-dir/server-source-maps/server-source-maps.test.ts`:
invalid source maps are not handled with the same graceful diagnostic as
webpack/Node source-map handling. Rspack logs the raw `webpack-internal`
frame for the damaged map case instead of surfacing the expected
`Invalid source map. Only conformant source maps...` message with the
cause.
-
`test/e2e/app-dir/parallel-routes-revalidation/parallel-routes-revalidation.test.ts`:
raw CI output observed a dev-mode timeout waiting for `networkidle`
after refresh/back/forward lazy fetching. This was not the final
structured failure in the latest run, but it remains a Rspack dev parity
follow-up around router cache lazy fetches and network settling.
- `test/e2e/middleware-src/middleware-src.test.ts`: after the test adds
root middleware files, Rspack dev still lets `src/middleware`
participate; the expected behavior is that only the root middleware
runs.
- `test/e2e/env-config/env-config.test.ts`: changing `.env` logs `Reload
env:` but the client keeps the previous `NEXT_PUBLIC_` value, pointing
at an Rspack dev env invalidation/HMR gap.
-
`test/e2e/app-dir/use-cache-without-experimental-flag/use-cache-without-experimental-flag.test.ts`:
after enabling the `useCache` flag, the dev server does not finish
restarting, pointing at build-error recovery/restart parity.
-
`test/development/app-dir/server-navigation-error/server-navigation-error.test.ts`:
middleware navigation-error cases hit `ERR_CONNECTION_REFUSED`,
consistent with the Rspack dev server exiting or restarting unexpectedly
during those error flows.
- `test/e2e/opentelemetry/instrumentation/opentelemetry.test.ts`: the
custom-server dev process exits before the SDK handle is initialized,
then cleanup fails on `shutdown`; this needs follow-up in Rspack
dev/custom-server startup.
- `test/e2e/next-image-new/app-dir/app-dir.test.ts`: after toggling
image source, `onLoadingComplete` still reports the previous image
dimensions/source, pointing at an Rspack dev image/HMR or asset
invalidation parity issue.
- `test/e2e/node-cli-args/node-cli-args.test.ts`: on Node `20.19.x`,
`node --experimental-network-inspection` resolves instead of rejecting.
This looks like a Node-version behavior change rather than an Rspack
compiler issue.
Not attributed to this Rspack upgrade:
-
`test/e2e/app-dir/instant-navigation-testing-api/instant-navigation-testing-api.test.ts`
was marked by `scripts/pr-status.js` as a known flaky test across
branches.
-
`test/production/app-dir/build-output-prerender/build-output-prerender.test.ts`
ran in the webpack prod job and only differs by prerender error ordering
in the inline snapshot.
<!-- NEXT_JS_LLM_PR -->
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
rootParams is now available by default. the flag is removed.
There are still intentional limitations. For instance rootParams cannot
be used in route handlers and Server Actions. The feature will be
expanded with some support for this in the future.
## What?
Converts existing `createNext()` usage into `nextTestSetup()`.
`createNext()` was the setup step we had before `nextTestSetup()` was
added.
This PR focused on the simple conversion cases. There will be a
follow-up to complete the last few.
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
When SSR fails in development — whether the failing page is in the App Router or the Pages Router — Next.js falls back to rendering the Pages Router `/_error` page and serializes the original error into `__NEXT_DATA__.err`. The client bootstrap in `packages/next/src/client/ index.tsx` later re-throws a fresh `new Error(initialErr.message)` so that the dev overlay picks it up. The error-code SWC plugin stamps that new `Error` with the generic code mapped to `%s` in `errors.json` because the message argument is an identifier, not a statically-known string, which is how the overlay ended up showing the wrong code for errors like `UseCacheTimeoutError`.
The pipeline has two problems on the way to the overlay. First, `errorToJSON` in `packages/next/src/server/render.tsx` only copies the error's standard fields (`name`, `source`, `message`, `stack`, `digest`) into `__NEXT_DATA__.err`, so the real `__NEXT_ERROR_CODE` attached to the thrown error never reaches the client. Second, the subsequent rewrap in `getServerError` at `packages/next/src/server/dev/node-stack- frames.ts` creates yet another `new Error(...)` that the plugin stamps with the same generic code, clobbering anything the caller might have set on the rewrapped instance.
This change plumbs the code through. `errorToJSON` now also emits `__NEXT_ERROR_CODE` using `extractNextErrorCode` so the value survives JSON serialization into `__NEXT_DATA__.err`; the type in `packages/next/src/shared/lib/utils.ts` is updated to match. Both rewrap sites — the client bootstrap and `getServerError` — copy the code from the source error onto the fresh `Error` via `Object.defineProperty` with `enumerable: false` and `configurable: true`, matching how the plugin itself stores the property, which overrides the generic code the plugin stamped on the rewrapped instance. The `use-cache-hanging` e2e test snapshot is updated from `E394` to `E236` now that the real code surfaces in the dev overlay.
### What?
Changes Turbopack's error overlay to show specific SWC diagnostic
messages as the error title instead of generic messages like "Parsing
ecmascript source code failed" or "Ecmascript file had an error".
### Why?
Previously, all SWC parse/analysis errors in Turbopack showed a generic
title (e.g. "Parsing ecmascript source code failed") in the redbox
header, with the actual specific error message buried in the description
below the code frame. This made it harder for developers to quickly
understand what went wrong.
**Before:**
```
Parsing ecmascript source code failed
> 1 | export default () => <div/
| ^
Expected '>', got '<eof>'
```
**After:**
```
Expected '>', got '<eof>'
> 1 | export default () => <div/
| ^
Parsing ecmascript source code failed
```
### How?
**Core change** in
`turbopack/crates/turbopack-swc-utils/src/emitter.rs`:
When the `IssueEmitter` has a `self.title` set (the generic title like
"Parsing ecmascript source code failed"), the SWC diagnostic message is
now used as the issue title, and the generic title is demoted to the
description. When `self.title` is not set, the existing behavior is
preserved (first line of message becomes title, rest becomes
description).
**Test updates** across ~15 test files:
Updated all `isTurbopack` branches in test expectations to reflect the
swapped title/description. Only Turbopack-specific branches were
modified; webpack and rspack expectations are unchanged.
**New test suite** (`test/development/app-dir/ecmascript-error-title/`):
Dedicated tests verifying that both syntax errors (e.g. `Expected '>',
got '<eof>'`) and analysis errors (e.g. `the name 'Table' is defined
multiple times`) show the specific SWC message as the redbox title.
**Turbopack snapshot updates:**
4 snapshot files renamed to reflect new titles (e.g. `Parsing ecmascript
source code failed-*.txt` → `Expression expected-*.txt`).
---------
Co-authored-by: Claude <noreply@anthropic.com>
update @next/rspack-core version to 1.0.2 and update the snapshot
other changes:
- packages/next/src/build/webpack-config.ts
Adjusted configuration to account for differences in default node config
between Rspack and Webpack.
- packages/next/src/shared/lib/format-webpack-messages.ts
Added a fallback to moduleIdentifier in cases where Rspack does not
correctly populate moduleName.
1. Fixed the incremental update bug in buildChunkGraph.
2. Fixed a bug in Rspack's built-in CssChunkingPlugin.
For detailed release information, please see
https://github.com/web-infra-dev/rspack/releases.
Note: All the faulty Rspack test cases on GitHub, from what I can see,
either time out or also produce errors in Rspack version 1.5.0.
---------
Co-authored-by: Benjamin Woodruff <benjamin.woodruff@vercel.com>
The peerDeps are already bumped to 19.2.0 at
https://github.com/vercel/next.js/pull/84463, but the test/CNA templates
weren't updated as the `syncPagesRouterReact` value is always false at
the moment, which blocked the update.
Therefore, remove the `syncPagesRouterReact` condition to match the
actual peerDeps bump.
---------
Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
Co-authored-by: Sebastian Sebbie Silbermann <sebastian.silbermann@vercel.com>
This commit addresses the bugs where Hot Module Replacement (HMR) was
not functioning correctly in Rspack mode. Component edits would often
result in no update or a full page reload instead of a fast,
state-preserving refresh.
This commit implements a new, custom React Refresh plugin and runtime
specifically for Rspack, which correctly orchestrates the HMR lifecycle.
After fixing the workflow config for Rspack in #83677, we're now running
more Rspack tests with React 18 on the `canary` branch. A few snapshot
tests now need to be updated because of that. The special cases are the
same as what we already had for Turbopack + React 18.
Don't return the `Result:Err`, but turn into an issue and return `Unparseable`
Also fixes the location translation: Lightning CSS uses 1-based columns, while Turbopack uses 0-based column indices.
### What?
In development give the module factory a useful name, so it's clear in stack traces that this is the module evaluation part of the execution.
This also fixes some bugs with the stack trace parser, which seems to struggle if function names contain brackets. The automatically inferred function name would be the module id, which contains brackets.
Implements accessing root params (params segments that occur above root
layouts) via compiler-generated getters from the `next/root-params`
module:
```tsx
// app/[lang]/layout.tsx
// (there is no app/layout.tsx, this is the root layout)
import { lang } from "next/root-params";
// ^^^^ coresponds to the [lang] segment above this module
export default async function RootLayout({ children }) {
return (
<html lang={await lang()}>
<body>{children}</body>
</html>
);
}
```
- This API is only usable within server components (support for using it
in route handlers will be added in the future). It can be called
anywhere in the component tree, not just in a page or a layout.
- It **cannot be used in server actions**, because they're not tied to a
route.
- It will replace `unstable_rootParams`, which will be removed soon.
Note that we can also have multiple root layouts with distinct params,
like this:
```
app/product/[productId]/layout.tsx
app/brand/[brandId]/layout.tsx
```
In this case we'll generate getters for both `productId` and `brandId`.
They can be called anywhere, but they'll return `undefined` if used in a
subtree where a param isn't available.
Note that this PR does not yet generate type declarations for the
generated getters, essentially leaving them typed as `any`. This will be
handled in a follow up.
## Implementation notes
### Turbopack
We collect the root param names when analyzing the folder structure in
`app_structure.rs`. The set is then passed down (as a Vc) all the way to
`next_import_map.rs`, where we insert an alias to a virtual
`next/root-params.js` module. We use a `ImportMapping::Dynamic` to
generate its code lazily in a separate turbo task (which is the only
place that actually reads the root params). This avoids invalidating the
whole `ResolveOptionsContext` if the root params change.
### Webpack
We alias `next/root-params` to `next-root-params-loader`, which scans
the directory structure manually (i haven't found a good way to re-use
existing methods for doing this) and returns the generated module. Each
directory we traverse before finding a root layout is marked as a
`contextDependency`, which should invalidate the loader's result if new
files are added to any of them or if they get renamed, because it might
mean that the set of root params changed.
webpack-only at the moment since I have no easy stack to test this on in Turbopack until we sourcemap the Turbopack runtime.
This applies the same heuristic Chrome uses. For sources whose associated sourcemap ignores everyone of its sources, we ignore-list that source even if we didn't find a mapping. This is similar to other common heuristic where the closest mapping is used when no exact mapping exists.
# Enhance Layer Names with User-Friendly Descriptions
This PR improves the developer experience by enhancing layer names in Turbopack with user-friendly descriptions. Instead of just using internal identifiers like "app-client" or "app-rsc", the PR adds descriptive names like "Client Component Browser" or "Server Component" that better communicate the purpose of each layer to developers.
Key changes:
- Created a new `LayerName` struct that contains both the internal name and an optional user-friendly description
- Updated all layer references throughout the codebase to use this new structure
- Changed error message text from "Example import trace(s)" to "Import trace(s)" for more simplicty
These changes make error messages and debugging information more intuitive, helping developers better understand which part of the application is experiencing issues.
This pull request updates error recovery tests to improve compatibility
with the Rspack bundler by introducing an `isRspack` flag and modifying
test cases to handle Rspack-specific error formats. The changes ensure
that runtime and build errors are correctly detected and displayed when
using Rspack.
### Rspack Compatibility Updates:
* Introduced the `isRspack` flag to determine if Rspack is being used,
based on the `NEXT_RSPACK` environment variable. This flag replaces
direct checks of `process.env.NEXT_RSPACK` for better readability and
maintainability.
(`test/development/acceptance-app/error-recovery.test.ts`
[[1]](diffhunk://#diff-ed42d009889881804f76e500465e132e4aa1df75c8659119e1b5cff4d230b7cdR8-R9)
`test/development/acceptance/error-recovery.test.ts`
[[2]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91R9)
* Updated test cases in `error-recovery.test.ts` and
`acceptance-app/error-recovery.test.ts` to handle Rspack-specific error
messages. This includes adapting error expectations for syntax errors,
runtime errors, and build errors with the Rspack error format.
(`test/development/acceptance-app/error-recovery.test.ts`
[[1]](diffhunk://#diff-ed42d009889881804f76e500465e132e4aa1df75c8659119e1b5cff4d230b7cdR58-R79)
[[2]](diffhunk://#diff-ed42d009889881804f76e500465e132e4aa1df75c8659119e1b5cff4d230b7cdR574-R588)
[[3]](diffhunk://#diff-ed42d009889881804f76e500465e132e4aa1df75c8659119e1b5cff4d230b7cdR845-R872);
`test/development/acceptance/error-recovery.test.ts`
[[4]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91L58-R74)
[[5]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91L372-R394)
[[6]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91L755-R766)
* Replaced outdated error message formats in Rspack-related test cases
with updated and more precise error descriptions, including detailed
stack traces and error causes.
(`test/development/acceptance/error-recovery.test.ts`
[[1]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91L815-R835)
[[2]](diffhunk://#diff-18cc654bcba9dbffcf77a6157fec144f9d0b1a0b3c59d46b33f6a2b95f543a91L883-R903)
These changes improve test coverage for Rspack and ensure robust error
handling across different bundlers.
### What?
Use CSS string for CSS errors instead of Rust debug representation, and remove `lightningcss` text from the error message.
### Why?
We don't need them.
When turbopack reports an issue, compute a set of import-traces for that file so the user can better understand the context of the issue and trivially answer questions like:
* Why is this file included at all?
* Why does next think this is a client-component?
To do this we leverage the `SingleModuleGraph` and use the `astar` algorithm from `petgraph` to compute the shortest path to a root module. This isn't the most optimal approach but should be sufficient since we don't anticipate this being a performance issue.
A complex part of this is that the module-graph tracks the relationships between _modules_ but Issues are associated with _files_. While modules are also associated with files this is a many-to-one relationship. This is why we might report _multiple_ traces for a single issue and also why a single file might appear multiple times in a trace.
## Open formatting questions
* how should we represent paths from other 'filesystems'?
- for disk filesystems i could compute relative paths to the root of the current directory? the `[project]` filesystem? For now i just use the filesystem name as a hypothetically cromulent root.
## Alternatives
The main alternative investigated was associating Issues with `Modules` by collecting them during graph construction. This unfortunately proved to be a non-trivial performance regression and so it was abandoned. The core problem is that we would need to introduce additional `OperationVc` and task roots to simply `collect` the issues. This also wouldn't eliminate the duplicate traces issue, and instead we might end up reporting duplicate issues instead.
## Performance
TODO
Closes PACK-4105