Build fails when the HTML entry is a symlink to a file outside root (Bazel sandbox)
Describe the bug
When the HTML entry inside root is a symlink to a file outside root, vite build fails:
[plugin vite:build-html]
RolldownError: The "fileName" or "name" properties of emitted chunks and assets must be strings that are neither absolute nor relative paths, received "../index.html".This is the layout of a Bazel sandbox (rules_js): the working directory is a real directory, and every input file in it is a symlink to the real file elsewhere. #21955 reported it from Bazel and was closed as fixed by #22832, but that fix only realpaths root itself. Here root is already a real path; the entry file is what points elsewhere. The resolver (now the Rust vite resolve plugin in rolldown) turns <root>/index.html into its real path, and vite:build-html then names the asset with path.relative(config.root, id), which starts with ../:
Vite 7 (rollup) fails the same way outside Bazel; it worked inside Bazel only because rules_js patches fs.realpath in Node, which the Rust resolver bypasses.
Workarounds that build fine:
resolve: { preserveSymlinks: true }root: fs.realpathSync(dirname(vite.config))plusbuild.outDir: path.resolve(process.cwd(), 'dist'), so the output still lands in the sandbox
Both change resolution for the whole project to fix the name of one output file. I think the HTML output name should come from the entry's input path (<root>/index.html), not from the resolved module id. Either the vite resolve plugin could leave HTML entries unresolved to their real path, or vite:build-html could map the resolved id back to the configured input before computing the relative path. Happy to send a PR for whichever you prefer.
Reproduction
https://github.com/u9g/vite-symlinked-entry-repro
Steps to reproduce
npm install
npm run reprorepro.sh creates sandbox/ containing a symlink to each project file and runs vite build from there. No Bazel needed.
System Info
System:
OS: macOS 27.0
CPU: (8) arm64 Apple M1
Shell: 5.9 - /bin/zsh
Binaries:
Node: 24.19.0
npm: 11.17.0
npmPackages:
vite: ^8.3.1 => 8.3.1 (rolldown 1.2.11)Used Package Manager
npm
Logs
vite v8.3.1 building client environment for production...
transforming...
✓ 4 modules transformed.
rendering chunks...
✗ Build failed in 1.11s
error during build:
Build failed with 1 error:
[plugin vite:build-html]
RolldownError: The "fileName" or "name" properties of emitted chunks and assets must be strings that are neither absolute nor relative paths, received "../index.html".
at error (node_modules/rolldown/dist/shared/logs-D6uA606S.mjs:166:24)
at PluginContextImpl.emitFile (node_modules/rolldown/dist/shared/bindingify-input-options-XrReX_BJ.mjs:1353:82)
at PluginContextImpl.generateBundle (node_modules/vite/dist/node/chunks/node.js:31808:10)Validations
- Follow our Code of Conduct
- Read the Contributing Guidelines.
- Read the docs.
- Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
- Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
- The provided reproduction is a minimal reproducible example of the bug.
Source: vitejs/vite