Skip to content

[pull] canary from vercel:canary#1101

Merged
pull[bot] merged 3 commits into
code:canaryfrom
vercel:canary
Jun 4, 2026
Merged

[pull] canary from vercel:canary#1101
pull[bot] merged 3 commits into
code:canaryfrom
vercel:canary

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Jun 4, 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 : )

sampoder and others added 3 commits June 4, 2026 09:42
…ded (#94376)

There's a lot of code in the runtime that enables top-level async
support. We may not always need to ship this. It makes up approximately
10% of the runtime. This PR separates this code into a separate module:
`async-module.ts`. This is included in the runtime based on this
condition:

```rust
!self.module_graph.async_module_info().await?.is_empty()
```

---------

Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com>
…94462)

This relands #94433, which was reverted in #94459 after it broke app
rendering in dev on React 18. The first commit reapplies the original
change verbatim, and the second commit fixes the regression that
prompted the revert.

The regression came from `connectReactDebugChannel` reaching into
`app-render/stream-ops.node` for its Node byte batcher transform. That
render-layer module carries unconditional `react-dom/server` and
`react-dom/static` value imports, and the dev server's hot-reloaders run
in the precompiled server runtime where `react-dom/*` is not aliased to
the vendored React. The `require` therefore resolved `react-dom/static`
against the app's installed React, which on React 18 has no `./static`
subpath export and threw `ERR_PACKAGE_PATH_NOT_EXPORTED`.

The fix extracts the batcher into its own React-free module,
`stream-utils/node-buffered-transform-stream`, which depends only on
`node:stream`. Both `stream-ops.node` and the debug channel import it
from there, so the dev server can batch Node stream chunks without
dragging the render layer's React imports into an unaliased runtime. The
debug channel's runtime branch on the stream type is unchanged and the
web path already used a React-free batcher, so no `.node`/`.web` split
is needed.
…4460)

### What?

Stop the Next.js TypeScript plugin from flagging the framework-injected
`unstable_retry` prop in `error.tsx` and `global-error.tsx` with error
`71007` (`INVALID_CLIENT_ENTRY_PROP`). The plugin already exempts
`reset`; this extends that exemption to `unstable_retry`.

### Why?

`unstable_retry` is injected by the framework into error boundaries: it
is part of the `ErrorInfo` type (`error`, `reset`, `unstable_retry`) in
`packages/next/src/client/components/error-boundary.tsx` and is passed
to the user's error component, not supplied by the user. Like `reset`,
it therefore does not need to be serializable.

The file-convention docs
(`docs/01-app/03-api-reference/03-file-conventions/error.mdx`) document
`unstable_retry` as an error-component prop (added in `v16.2.0`) and
recommend it over `reset`. The exact documented pattern, `export default
function Error({ error, unstable_retry })`, was being false-flagged by
the plugin, so a user copying the docs would hit a spurious diagnostic.

<img width="2930" height="1110" alt="image"
src="https://github.com/user-attachments/assets/7c7efefe-f9df-448a-9fd6-218c51bc8bd1"
/>

### How?

Extend the existing error-file `reset` exemption in
`packages/next/src/server/typescript/rules/client-boundary.ts` to also
allow `unstable_retry`. The exemption stays scoped to those two prop
names in `error` / `global-error` files; every other non-serializable
function prop is still flagged.

Add regression tests for both `error.tsx` and `global-error.tsx`, each
with a `_notExempt` negative control that confirms the exemption stays
scoped (an ordinary function prop is still flagged). Update the manual
VSCode fixtures and the test README to match.

### Verification

- `pnpm test-dev-turbo
test/development/typescript-plugin/client-boundary/client-boundary.test.ts`
(5/5 passed; the harness loads the compiled plugin from `dist`, so green
also confirms the build reflects the change)
- `pnpm --filter=next types` (passed)
- `pnpm --filter=next build` (passed)
- `pnpm typescript` root `tsc` for the changed test files (passed)
- Not run: full CI suite (will run on the PR)

<!-- NEXT_JS_LLM_PR -->
@pull pull Bot locked and limited conversation to collaborators Jun 4, 2026
@pull pull Bot added the ⤵️ pull label Jun 4, 2026
@pull pull Bot merged commit b58d984 into code:canary Jun 4, 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.

3 participants