Skip to content

[pull] canary from vercel:canary#1003

Merged
pull[bot] merged 5 commits intocode:canaryfrom
vercel:canary
Apr 27, 2026
Merged

[pull] canary from vercel:canary#1003
pull[bot] merged 5 commits intocode:canaryfrom
vercel:canary

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented Apr 27, 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 : )

ztanner and others added 5 commits April 27, 2026 07:55
Moves all release workflows off of a GH PAT and uses an app with a
short-lived token instead.

Test Plan:
Dry run
[here](https://github.com/vercel/next.js/actions/runs/24934593874).

However, this workflow is blocked until we figure out commit signing for
the bot app. Some options:
- The bot account generates a signing key and we use it in CI (not
great, bypasses the app)
- The org bypasses signature verification for the bot user (also not
great, requires an exemption rule)
- We need to rework the commit step so Lerna does not do the push, and
instead trigger it via the app + GH API. This seems like the best
option, will be added in a follow-up PR.

Note: `create-release-branch` workflow is broken in its current form, as
we will not be restoring administrator privileges to adjust environment
settings. This will become a manual step in the future.
…ling (#93179)

## What?

Performance improvements for the turbopack-trace-server, optimizing how
span events are stored, sorted, and retrieved.

## Why?

When processing large traces, the trace server was spending significant
time on:
1. Repeated sorting of events for each render in ExecutionOrder mode
2. Recomputing corrected self time on repeated lookups
3. Memory pressure from very large traces

## How?

### Lazy Sorting with LazySortedVec

Introduces a new `LazySortedVec<T>` data structure that stores events
unsorted and defers sorting until first read via `Deref`. Uses
`UnsafeCell` + `Once` for thread-safe one-time sorting. This avoids
repeated sorting overhead during trace ingestion.

### Pre-sorted Span Events by Start Time

- `SpanEvent::Child` now stores its `start: Timestamp` alongside the
index
- `SpanEvent` implements `Ord` to sort by start time (with SelfTime
before Child for equal timestamps)
- The viewer's `ExecutionOrder` mode no longer needs to sort - events
are already in order

### Cached Corrected Self Time

- `SpanEvent::SelfTime` now wraps a `SpanEventSelfTime` struct
containing an `OnceLock<Timestamp>` for `corrected_self_time`
- The expensive tree lookup is performed once and cached for subsequent
accesses
- `SpanEventSelfTimeRef` provides access to the cached value via
`corrected_self_time()`

### DROP_SPANS Environment Variable

Adds `DROP_SPANS=<count>` env var to skip the first N spans when loading
traces:
- Useful for reducing memory usage with very large traces
- Tracks dropped span IDs to also skip their subsequent events (End,
SelfTime, etc.)
- Stats output shows dropped span progress (e.g., "1000 spans, 500/1000
dropped")

<!-- NEXT_JS_LLM_PR -->

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Stacked on #93245

Commit signing is required for anything that lands on `canary`. Our
previous workflow of using a PAT to push a commit no longer works, since
that would have been an unsigned commit.

In #93245 we switched to an app token for release workflow steps. This
continues by:

- Telling Lerna to bump packages but not commit
- Creating a signed commit with the staged changes via GitHub's API
- Then running the publish flow

Test Plan:
Dry run
[here](https://github.com/vercel/next.js/actions/runs/25001287978/job/73211826479)
Commit
[here](3a8456a)
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.
@pull pull Bot locked and limited conversation to collaborators Apr 27, 2026
@pull pull Bot added the ⤵️ pull label Apr 27, 2026
@pull pull Bot merged commit d2e6b6c into code:canary Apr 27, 2026
3 of 6 checks passed
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