mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
#95815 refactored the NFT flow and ended up only tracing the RSC template and it's subgraph. Not the server actions loader module whose module graph is completely separate. --- Clauded. Attempts to fix https://github.com/vercel/next.js/discussions/95130#discussioncomment-17652155. --- <details> ## Summary Fixes the NFT tracing regression behind #95815 and the deploy failures reported in https://github.com/vercel/next.js/issues/87737#issuecomment-4897366831. Since the 16.3 NFT rewrite (#94224 / #92901), a `serverExternalPackages` entry that is imported **only from a `'use server'` action referenced by a client component** ends up in the route's trace as the content-hashed alias symlink (`.next/node_modules/<pkg>-<hash>`) **without the store files the symlink points to**. Any output assembled from the traces (Vercel lambdas, `output: 'standalone'`) then contains a dangling symlink, and invoking the action throws `Failed to load external module <pkg>-<hash>` (HTTP 500). 16.2.9 traces both. Both CJS and ESM externals are affected, with any package manager — the ESM/bun/monorepo framing in the issue reports was a coincidence of which packages were only reachable through actions. The cause: `AppEndpoint::trace_result` started the trace DFS only from `rsc_entry`, but the server actions loader is a separate module-graph entry (`additional_entries`). It is chunked into the endpoint output (which emits the alias symlink via the chunk's output assets), yet its subgraph — including the externals' traced target files — was never visited by the tracer. `trace_endpoint` now accepts multiple entry modules and the app endpoint passes the actions loader alongside `rsc_entry`. The test observes the user-visible failure: it builds with `output: 'standalone'`, deletes everything except the standalone output (so only traced files are available, like a deployed lambda), runs `server.js`, and invokes the server action in a browser. Without the fix the action fails with `Failed to load external module lodash-<hash>`; on 16.2.9 the same fixture responds with the action result. Note the fixture must not import the externals from any other route: the standalone output is the union of all route traces, so a route that traces them correctly would mask the missing entries. ## Verification - `pnpm test-start-turbo test/production/standalone-mode/server-action-externals/standalone-mode-server-action-externals.test.ts` — fails without the fix (`Failed to load external module lodash-fb78ad0536ffcdab` from the standalone server), passes with it. The equivalent standalone flow on `[email protected]` returns the action result with HTTP 200. - `pnpm test-start-turbo test/e2e/externals-transitive/externals-transitive.test.ts` - `pnpm test-start-turbo test/production/standalone-mode/server-actions/standalone-mode-server-actions.test.ts` <!-- NEXT_JS_LLM --> </details>