vercel / vercel/next.js

Client reference is dropped from the manifest when the concatenated module's id is 0

Open
#97,937 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Webpack
Dominant language
JavaScript
Stars
142k
Forks
32.4k
Avg merge
2d 14h
Merged PRs (30d)
351

Description

Link to the code that reproduces this issue

https://github.com/jgruica/next-concat-modid-zero

To Reproduce
  1. Clone the reproduction and run pnpm install
  2. Run pnpm build
  3. Observe that the build fails during prerendering
Current vs. Expected behavior

ClientReferenceManifestPlugin walks each client entry and resolves its module id:
https://github.com/vercel/next.js/blob/d09816fdaf2fef7a23751de75a9dde6bb7c2403b/packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts#L512C15-L532C12

const modId = compilation.chunkGraph.getModuleId(
  clientEntryMod
) as string | number | null

if (modId !== null) {
  recordModule(modId, clientEntryMod)
} else {
  // If this is a concatenation, register each child to the parent ID.
  if (
    connection.module?.constructor.name === 'ConcatenatedModule'
  ) {
    const concatenatedMod = connection.module
    const concatenatedModId =
      compilation.chunkGraph.getModuleId(concatenatedMod)
    if (concatenatedModId) {
      recordModule(concatenatedModId, clientEntryMod)
    }
  }
}

The return type is annotated string | number | null right at the call site, and 0 is a valid module id. The first check respects that and tests modId !== null. The fallback a few lines below tests truthiness instead, so when the enclosing ConcatenatedModule is assigned id 0, recordModule is never called.

Expected: the client entry appears in clientModules in the generated *_client-reference-manifest.js, keyed by the concatenated module's id 0.

Current: the entry is omitted from the manifest and the build fails during prerendering:

  Creating an optimized production build ...

[repro] client entry resolved to a ConcatenatedModule with id 0
[repro]   javascript/auto|/Users/jelena/next-concat-modid-zero/node_modules/.pnpm/next@16.4.0-canary.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/next/dist/build/webpack/loaders/next-flight-client-module-loader.js!/Users/jelena/next-concat-modid-zero/node_modules/.pnpm/next@16.4.0-canary.8_react-dom@19.2.8_react@19.2.8__react@19.2.8/node_modules/next/dist/build/webpack/loaders/next-swc-loader.js??ruleSet[1].rules[17].oneOf[6].use[1]!/Users/jelena/next-concat-modid-zero/app/barrel.js|app-pages-browser
[repro]   has an id, should be recorded

Changing the fallback guard to concatenatedModId !== null makes the same build pass.

Provide environment information
Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.6.0: Wed May 14 13:52:22 PDT 2025; root:xnu-10063.141.1.705.2~2/RELEASE_ARM64_T6000
  Available memory (MB): 32768
  Available CPU cores: 10
Binaries:
  Node: 24.1.0
  npm: 11.3.0
  Yarn: N/A
  pnpm: 10.33.2
Relevant Packages:
  next: 16.4.0-canary.8
  eslint-config-next: N/A
  react: 19.2.8
  react-dom: 19.2.8
  typescript: N/A
Next.js Config:
  output: N/A
Which area(s) are affected? (Select all that apply)

Webpack

Which stage(s) are affected? (Select all that apply)

next build (local)

Additional context

Not a regression. The truthiness check has been there since this fallback was added, so there's no canary release to bisect to.
The reproduction uses some non-default webpack config on purpose. Three things have to line up:

  1. next build --webpack. Turbopack is the default in Next 16, so nobody on the default builder is affected.
  2. optimization.concatenateModules = true. The client build doesn't produce any ConcatenatedModule`s as configured, so without this the fallback branch never runs.
  3. The ConcatenatedModule has to get id 0. The repo forces this so the build fails every time, but 0 is a normal id. The production default (deterministic) uses numberHash(ident, range), which returns 0 to range-1. Without forcing it you'd just rebuild until the hash landed on 0.

So not many people will hit this. I'm filing it because the two checks sit a few lines apart and disagree about whether 0 is a valid id, which looks like an oversight.

PR https://github.com/vercel/next.js/pull/97936

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/next/src/build/webpack/plugins/flight-manifest-plugin.ts at the ClientReferenceManifestPlugin fallback linked in the issue. Run the reproduction with pnpm install and pnpm build, then verify that a concatenated module with id 0 is included in clientModules in the generated client-reference manifest and that prerendering succeeds.

Written by the indexing model from the issue text.

Assessment

Tech stack
next.js, typescript, webpack
Domain
build-system
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.