Skip to content

Wrong entry bundle selected when multiple chunks have name: "index" #1060

@altinokdarici

Description

@altinokdarici

Related plugins

Describe the bug

Description

In @vitejs/[email protected], the plugin incorrectly selects the bootstrap script entry when multiple chunks in the Vite manifest have name: "index". This causes React client hydration to fail completely because the wrong JavaScript bundle is imported in the generated HTML.

Root Cause

In /dist/plugin-BIsCR7Tu.js around line 100, the code finds the entry chunk like this:

const assetDeps = collectAssetDeps(bundle);
const entry = Object.values(assetDeps).find((v) => v.chunk.name === "index");
assert(entry);
const entryUrl = assetsURL(entry.chunk.fileName, manager);

The problem: When multiple chunks have name: "index", find() returns the FIRST match, not the actual entry client bundle. It should check for isEntry: true to identify the real entry point.

Suggested Fix

Change the entry finding logic to check for isEntry: true:

const entry = Object.values(assetDeps).find((v) => v.chunk.name === "index" && v.chunk.isEntry);

Reproduction

It's hard to reproduce this issue in a small app. I'll try to create one again if you really need it. Please check the info in the steps to reproduce

Steps to reproduce

This bug occurs in React Router 7.11.0 apps using RSC Framework Mode when the build produces multiple chunks named "index" (common in monorepos or projects with component libraries that export from index files).

Steps to Reproduce

  • Create a React Router 7.11.0 app with RSC Framework Mode
  • Set up a monorepo structure with shared packages that export from index.js or index.ts files
  • Include shared components/utilities that result in multiple Vite chunks named "index"
  • Build the project with react-router build
  • Inspect the generated HTML in build/server/index.js or view source in browser
  • Notice the <script id="_R_"> tag imports the wrong bundle (not the entry client)

Expected Structure for Reproduction

my-app/
├── app/
│ └── routes/
│ └── _index.tsx
├── packages/
│ ├── ui-components/
│ │ └── index.ts # Exports multiple components
│ └── icons/
│ └── index.ts # Exports icon assets
└── package.json


Example Manifest Showing the Bug

When the build completes, build/client/.vite/manifest.json contains multiple entries with name: "index":

{
  "../../packages/ui-components/index.js": {
    "file": "assets/index-ABC123.js",
    "name": "index",
    "isDynamicEntry": true
  },
  "../../packages/icons/index.js": {
    "file": "assets/index-DEF456.js",
    "name": "index",
    "isDynamicEntry": true
  },
  "_index--GHI789.js": {
    "file": "assets/index--GHI789.js",
    "name": "index"
  },
  "node_modules/@react-router/dev/dist/config/default-rsc-entries/entry.client.tsx": {
    "file": "assets/index-JKL012.js",
    "name": "index",
    "isEntry": true,  // ← This is the correct entry!
    "isDynamicEntry": true
  }
}

System Info

System:
    OS: macOS 26.2
    CPU: (8) arm64 Apple M1 Pro
    Memory: 188.22 MB / 16.00 GB
    Shell: 5.9 - /bin/zsh
  Binaries:
    Node: 24.11.0 - ~/.nvm/versions/node/v24.11.0/bin/node
    Yarn: 4.12.0 - ~/.nvm/versions/node/v22.18.0/bin/yarn
    npm: 11.6.1 - ~/.nvm/versions/node/v24.11.0/bin/npm
  Browsers:
    Chrome: 143.0.7499.193
    Edge: 143.0.3650.139
    Safari: 26.2
  npmPackages:
    @vitejs/plugin-rsc: 0.5.7 => 0.5.7

Used Package Manager

yarn

Logs

No response

Validations

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions