Next.js printed a stack frame that does not exist for an error whose
message ends with text that looks like a file location. A logged
connection failure read `at <unknown> (Error: connect ECONNREFUSED
::1:45999)` in front of its real frames.
`stacktrace-parser` tries five patterns on every line, and the pattern
for JavaScriptCore makes the `<name>@` prefix optional. That pattern
`:<line>:<column>`, and a line of an error message can end that way. A
JavaScriptCore frame always holds `@`, also at the top level, so the
prefix is not optional in a real stack.
The patch for `stacktrace-parser` now requires that prefix. A line of a
message no longer becomes a frame, and every JavaScriptCore frame still
parses, including one whose path holds a space.
A Turbopack build error puts the file and the position of the error in
its message, and the parser read that line as a frame as well. That
frame is gone now, and the location stays in the message. The snapshots
of the build errors record the change.
A failed `fetch` hid the reason of the failure. Node.js reports every
refused connection attempt in the `errors` of an `AggregateError`, and
the terminal logged `[errors]: [ [Error], [Error] ]` without the address
or the port of a single attempt.
An `AggregateError` keeps its errors in an array. Node.js spends one
level of the inspect depth on that array, and one more level on each
error in the array, while a `cause` costs one level only. The errors of
an `AggregateError` behind a cause therefore fell outside the default
depth of two. Node.js also returns an error early when it carries no own
properties, before it applies the depth, so the collapse hit only the
errors that carry diagnostics.
Next.js now adds the missing level back for an `AggregateError`, so its
errors print at the same nesting as a cause. A depth of `null` means
unlimited and stays unchanged, because `null + 1` would reduce it to one
level.
Adds tests verifying that`use cache` stacks get symbolicated.
We noticed insufficient coverage in
https://github.com/vercel/next.js/pull/95936, which should have failed
the tests (it broke symbolication) but tests passed. So this restores
the missing stack assertions. This also adds some new coverage that
specifically verifies that symbolicating via CDP also works.
### What?
Flips the default `experimental.instantInsights.validationLevel` from
`'manual-warning'` to `'warning'` so Cache Components apps get
instant-navigation validation across all pages by default.
### Why?
`'manual-warning'` only validates pages that explicitly export
`unstable_instant`, so apps see nothing unless they opt in. `'warning'`
is what users have been turning on manually to actually see the feature
(`v0`, `vercel-site`).
### Test coverage
- Unit: `instant-config-normalization.test.ts` pins the framework
default at `'warning'`.
- Integration: new `instant-validation-level-default/` fixture (no
`instantInsights` in config) asserts implicit dev validation fires, and
that build is unaffected.
### Collateral test fixtures
Tests whose intent is unrelated to instant validation
(router-autoscroll, owner-stack, hmr-iframe, next-image,
server-source-maps, etc.) now hit new redboxes/console warnings because
their fixtures incidentally use dynamic data. Each opts out with
`experimental: { instantInsights: { validationLevel: 'manual-warning' }
}` in `next.config`.
### Open question
With no `'off'` / `'info'` tier today, silencing Insights after this
change requires setting `validationLevel: 'manual-warning'`. Is that
acceptable? Should we inform of this anywhere?
<!-- NEXT_JS_LLM_PR -->
When the Node.js inspector is active (e.g. via `next dev --inspect`),
dimming wraps console arguments in a format string which defeats
inspector affordances such as collapsible objects and
clickable/linkified stack traces.
This adds an early return in `convertToDimmedArgs` that skips dimming
entirely when `inspector.url()` is defined. Terminal output without
`--inspect` is unchanged.
Ideally we would only skip dimming when a debugger frontend is actually
attached, but Node.js does not expose a synchronous API for that —
detecting it would require async polling of the `/json/list` HTTP
endpoint.
Test plan:
- Unit tests in `console-dim.external.test.ts`
- Manual: dimming almost never triggers now since we switched to in-band
validation (no separate render pass). To reproduce manually, use a
client component that calls `console.error(new Error(...))` during SSR,
e.g.:
1. `__NEXT_CACHE_COMPONENTS=true pnpm next dev
test/e2e/app-dir/server-source-maps/fixtures/default --inspect`
2. Open `http://localhost:3000/` in Chrome
3. Click the Node.js DevTools button
4. Load `http://localhost:3000/ssr-error-log`
5. Verify the first error in DevTools has source-mapped, expandable
stack frames
Before:
<img width="1496" height="848" alt="before"
src="https://github.com/user-attachments/assets/8b4358e1-06ec-4078-b6cc-269986e295e7"
/>
After:
<img width="1496" height="842" alt="after"
src="https://github.com/user-attachments/assets/42f33c6f-f025-410f-b44c-2ccd88fe0cfe"
/>
This moves `experimental.cacheComponents` to a top level config. As part
of this, I disabled some tests in `build-output-prerender` that assert
on `cacheComponents` appearing in the experimental list. In a separate
PR, I'm going to show that Cache Components is enabled next to the
bundler info.
This also updates some docs pages to remove "experimental" language.
## What?
Rename `experimental.dynamicIO` to `experimental.cacheComponents` across
the Next.js codebase.
## Why?
We're going to be merging the functionality of the `ppr`, `dynamicIO`
and `useCache` experimental flags into the singular `cacheComponents`
flag to reduce complexity of the codebase and simplify adoption for
users wanting to experiment with experimental features.
## How?
- Renamed the configuration option from `experimental.dynamicIO` to
`experimental.cacheComponents`
- Added deprecation handling with automatic migration for the old option
name
- Updated all documentation, tests, and internal references
- Updated Rust code in SWC transforms and Turbopack
- Maintained backward compatibility with deprecation warnings
NAR-158
Allows unambigious assertions on CLI output.
Not that interesting for dev but `next build` will have the logs for all pages in all tests.
I also made the pages static where possible so that we'll be able to assert on the logged errors during `next build`.
To prepare for an upcoming change where `ppr` will be enabled
automatically when `dynamicIO` is enabled, we're hard coding `ppr: true`
in the Dynamic IO tests with this PR. The non-PPR assertions are
subsequently removed, which makes up most of the changed lines.
We can now also exclude the tests in the PPR tests manifest, so that
they're not run twice in CI.
> [!NOTE]
> This PR is best reviewed with hidden whitespace changes.
If `--inspect` or `--inspect-brk` is specified, prerender will no longer time out since that's most likely not wanted (e.g. you'd always get timeouts if you set breakpoints).
Inspecting prerender workers is best done with `experimental.cpus: 1`.
Only the first prerender worker can be inspected since we can't set `NODE_OPTIONS` based off of the worker index.
This PR also sets up infra for inspecting arbitrary workers. Their debug port would need to be coordinated within `getNextBuildDebuggerPortOffset`. This doesn't work if worker creation is shared between `next build` and `next dev` which I haven't checked if that's the case.
We already create server source maps in dev by default,
so we should make use of them.
To opt-out, run `next dev --disable-source-maps` instead.
Our internal `next-no-sourcemaps` script is now defunct.