Skip to content

[pull] canary from vercel:canary#1061

Merged
pull[bot] merged 5 commits into
code:canaryfrom
vercel:canary
May 20, 2026
Merged

[pull] canary from vercel:canary#1061
pull[bot] merged 5 commits into
code:canaryfrom
vercel:canary

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 20, 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 : )

mischnic and others added 5 commits May 20, 2026 10:08
Closes #93295
Closes #93914

https://nodejs.org/api/packages.html#subpath-exports:

> All target paths in the
["exports"](https://nodejs.org/api/packages.html#exports) map (the
values associated with export keys) must be relative URL strings
starting with `./`

but

>Unlike the "exports" field, the "imports" field permits mapping to
external packages.
>The resolution rules for the imports field are otherwise analogous to
the exports field.
### What?

When a Turbopack webpack-loader subprocess crashes (e.g. a loader calls
`process.exit()`, a native fatal error, or the IPC socket otherwise
closes mid-message), the error users see today is:

```
- Execution of <WebpackLoadersProcessedAsset as Asset>::content failed
- Execution of WebpackLoadersProcessedAsset::process failed
- Execution of evaluate_webpack_loader failed
- failed to receive message
- reading packet length
- unexpected end of file
```

After this PR, the same crash produces:

```
⨯ ./data/crash.data
Error evaluating Node.js code
Error: Node.js subprocess crashed while evaluating loaders [/path/to/loaders/crash-loader.js]: failed to receive message

Caused by:
- Node.js process exited with exit status: 7
- reading packet length
- unexpected end of file

Debug info:
- failed to receive message
- Node.js process exited with exit status: 7
  Recent process stderr:
  <whatever the loader wrote to stderr before exiting>
- reading packet length
- unexpected end of file
```

### Why?

The original message gave no actionable information: no exit code, no
captured stdout/stderr, no indication of which loader was running. It
also looked like an internal turbopack bug rather than a user-fixable
error, and a transient pool failure could cascade into an unrelated
"issue formatter crashed while reading the source for a code frame"
failure on the way out.

### How?

Four orthogonal fixes, plus a regression test:

1. **Capture stdout/stderr on subprocess crash.** `OutputStreamHandler`
now keeps a bounded ring buffer (last 100 lines per stream) shared with
the owning `NodeJsPoolProcess`. When `NodeJsPoolProcess::recv` fails,
the buffers and the child's exit status are attached to the error via
`anyhow::Error::context`.
2. **Recover from subprocess crash in `pull_operation`.** Instead of
propagating the recv error up through `evaluate_webpack_loader` →
`process()` → `Asset::content` (the cascade above), `pull_operation`
catches it, synthesizes a `StructuredError` via
`evaluate_context.emit_error(...)`, disables process reuse, and returns
`Ok(None)`. This mirrors the existing in-band loader-error path, so the
asset's existing `FileContent::NotFound` degradation kicks in naturally
— `Asset::content` never errors.
3. **Include the loader chain in the error message and issue detail.**
`WebpackLoaderContext` gained a `loader_names: Vec<RcStr>` field. A new
optional `EvaluateContext::crash_context_prefix()` trait method lets
webpack-loader evaluations describe what was being evaluated (\"loaders
[a, b, c]\") in the synthesized crash message. `EvaluationIssue` also
gained an optional `detail` field for the same chain, surfacing it in
`--log-detail` output. PostCSS evaluations are labelled \"postcss\".
4. **Crash-proof the issue formatter.** `PlainSource::from_source` and
`IssueSource::into_plain` previously propagated errors from
`asset.content()` with `?`. They now degrade to `FileContent::NotFound`
(and `range = None`) on read failure, so a future regression in some
other code path can never cause the issue reporter itself to crash on
top of whatever the user was debugging.

### Tests

- Added
`test/e2e/app-dir/webpack-loader-errors/loaders/crash-loader.js`: a
loader that writes a marker to stderr and calls `process.exit(7)`.
- Added an e2e test that fetches `/crash` and asserts the marker, the
absence of the internal cascade, the loader name, and the resource name
are all present in the CLI output.
- All 11 tests in `webpack-loader-errors.test.ts` pass; the 5 Rust
`turbopack-node` pool tests still pass.

Some snapshot/golden tests for error formatting may need updating in CI
since `EvaluationIssue` now emits a non-empty `detail`.

<!-- NEXT_JS_LLM_PR -->
4.15 made [npmMinimalAgeGate: 1d the
default](yarnpkg/berry#7135)

1. Pin yarn version to prevent random breakages in the future
2. Add trusted packages to ignore npmMinimalAgeGate for them

https://github.com/yarnpkg/berry/releases/tag/%40yarnpkg%2Fcli%2F4.15.0
### What?

- Rename cards to plain English: `Prerender params if known`, `Mark the
route as dynamic`, `For telemetry, use a timing API`.
- Remove `Wrap body in Suspense` card from viewport variants.
- Body errors: `during the initial render` → `during prerendering`;
`blocking navigation` → `blocking the page load`.
- Server sync IO leads with `the unstable value <expression>`.
- Client sync IO drops `fixed at build time`.
- New loading-state icon for the `block` group.

### Demo

- [Fix
Overview](https://error-messages-overhaul-ibsl.labs.vercel.dev/fix-overview)

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
@pull pull Bot locked and limited conversation to collaborators May 20, 2026
@pull pull Bot added the ⤵️ pull label May 20, 2026
@pull pull Bot merged commit 4e3eb51 into code:canary May 20, 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