vitejs/vite · error · Error
failed to resolve rolldownOptions.input value
Error message
failed to resolve rolldownOptions.input value: ${JSON.stringify(p)}. What it means
Thrown during dependency scanning when `rolldownOptions.input` (or `build.rolldownOptions.input`, or `environment.config.input`) is set, and one of its values cannot be resolved to a file id by Vite's plugin container. `resolvePath` returns undefined and scan.ts:231 throws, naming the offending input value via JSON.stringify.
Solutions
- Verify the input path exists and is resolvable from the project root; print it with `console.log(path.resolve(input))`.
- If it is a bare specifier or virtual id, add a plugin that resolves it during the scan (handle `isEntry: true, scan: true`).
- Use `optimizeDeps.entries` with glob patterns for HTML/JS files instead of a single missing path.
- Fix or remove aliases that are misconfigured for the scan phase.
- Ensure the file is present on disk (un-ignore, restore from git, reinstall workspace).
Example fix
// before
export default defineConfig({
build: { rollupOptions: { input: './src/main.html' } }, // typo, real file is index.html
})
// after
export default defineConfig({
build: { rollupOptions: { input: './index.html' } },
}) Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs'
import path from 'node:path'
function resolveInput(input: unknown, root: string): string[] {
const list: string[] = typeof input === 'string' ? [input]
: Array.isArray(input) ? input
: isObject(input) ? Object.values(input)
: []
for (const p of list) {
const abs = path.isAbsolute(p) ? p : path.resolve(root, p)
if (!fs.existsSync(abs)) throw new Error(`build.rolldownOptions.input '${p}' does not resolve to an existing file`)
}
return list
}
// call resolveInput(config.build.rolldownOptions.input, config.root) before server start Type guard
function isInputValue(v: unknown): v is string | string[] | Record<string, string> {
return typeof v === 'string' || Array.isArray(v) || (typeof v === 'object' && v !== null && !Array.isArray(v))
} Try / catch
try {
await server.listen()
} catch (e) {
if (e instanceof Error && /failed to resolve rolldownOptions\.input value:/.test(e.message)) {
const val = e.message.match(/value: (.*)\./)?.[1]
console.error(`Input ${val} could not be resolved; check path/alias and retry.`)
}
throw e
} Prevention
- Keep build input paths relative to project root and verify they exist in a prebuild check.
- Add aliases/plugins that resolve virtual inputs during the scan phase (isEntry:true, scan:true).
- Prefer glob-based optimizeDeps.entries over fragile single-path inputs.
When it happens
Trigger: Config sets `build.rollupOptions.input` / `optimizeDeps.entries` / environment `input` to a path or bare specifier that `pluginContainer.resolveId(p, undefined, { isEntry: true, scan: true })` cannot resolve. Triggered at server/build startup during `computeEntries`.
Common situations: Typo in the input path. Path relative to wrong root (input must be resolvable from project root, or absolute). Input points to a virtual module not handled by a plugin during scan. File was deleted or gitignored. Monorepo where the input lives in another package not symlinked. Conditional alias not active during scan.
Related errors
- invalid rolldownOptions.input value.
- Could not resolve " " imported by " ". Is it installed?
- `input` cannot contain glob characters. They are reserved…
- not implemented
- The following dependencies are imported but could not be…
AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11).
Data as JSON: /api/errors/2f81105f1612efa2.
Report an issue: GitHub.
Appendix: source
Thrown at packages/vite/src/node/optimizer/scan.ts:231
async function computeEntries(environment: ScanEnvironment) {
let entries: string[] = []
const explicitEntryPatterns = environment.config.optimizeDeps.entries
const input =
environment.config.input ?? environment.config.build.rolldownOptions.input
if (explicitEntryPatterns) {
entries = await globEntries(explicitEntryPatterns, environment)
} else if (input) {
const resolvePath = async (p: string) => {
const id = (
await environment.pluginContainer.resolveId(p, undefined, {
isEntry: true,
scan: true,
})
)?.id
if (id === undefined) {
throw new Error(
`failed to resolve rolldownOptions.input value: ${JSON.stringify(p)}.`,
)
}
return id
}
if (typeof input === 'string') {
entries = [await resolvePath(input)]
} else if (Array.isArray(input)) {
entries = await Promise.all(input.map(resolvePath))
} else if (isObject(input)) {
entries = await Promise.all(Object.values(input).map(resolvePath))
} else {
throw new Error('invalid rolldownOptions.input value.')
}
} else {
entries = await globEntries('**/*.html', environment)
}
View on GitHub (pinned to b4d66fee14)