{"id":"768909f032203b37","repo":"vitejs/vite","slug":"rolldownoptions-input-should-not-be-an-html-file-w","errorCode":null,"errorMessage":"rolldownOptions.input should not be an html file when building for SSR. Please specify a dedicated SSR entry.","messagePattern":"rolldownOptions\\.input should not be an html file when building for SSR\\. Please specify a dedicated SSR entry\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/vite/src/node/build.ts","lineNumber":628,"sourceCode":"  const input = libOptions\n    ? options.rolldownOptions.input ||\n      (typeof libOptions.entry === 'string'\n        ? resolve(libOptions.entry)\n        : Array.isArray(libOptions.entry)\n          ? libOptions.entry.map(resolve)\n          : Object.fromEntries(\n              Object.entries(libOptions.entry!).map(([alias, file]) => [\n                alias,\n                resolve(file),\n              ]),\n            ))\n    : typeof options.ssr === 'string'\n      ? resolve(options.ssr)\n      : options.rolldownOptions.input ||\n        (topLevelInput ?? resolve('index.html'))\n\n  if (ssr && typeof input === 'string' && input.endsWith('.html')) {\n    throw new Error(\n      `rolldownOptions.input should not be an html file when building for SSR. ` +\n        `Please specify a dedicated SSR entry.`,\n    )\n  }\n  if (options.cssCodeSplit === false) {\n    const inputs =\n      typeof input === 'string'\n        ? [input]\n        : Array.isArray(input)\n          ? input\n          : Object.values(input)\n    if (inputs.some((input) => input.endsWith('.css'))) {\n      throw new Error(\n        `When \"build.cssCodeSplit: false\" is set, \"rolldownOptions.input\" should not include CSS files.`,\n      )\n    }\n  }\n","sourceCodeStart":610,"sourceCodeEnd":646,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/vite/src/node/build.ts#L610-L646","documentation":"In resolveRolldownOptions (build.ts:627), when building for SSR (environment consumer === 'server') and the resolved input is a string ending in .html, Vite throws. An HTML entry is a client-side document and cannot serve as an SSR bundle entry; SSR needs a dedicated JS/TS entry module.","triggerScenarios":"Running an SSR build where the input defaults to index.html (because no SSR entry was given), or explicitly passing an .html file as rolldownOptions.input while consumer is 'server'.","commonSituations":"Forgetting to set build.ssr to a server entry string and letting it default to index.html; migrating from client-only to SSR without adding a server entry.","solutions":["Provide a dedicated SSR entry, e.g. build: { ssr: 'src/entry-server.ts' }.","Or set rollupOptions/rolldownOptions.input to a .js/.ts server entry instead of index.html.","Confirm the environment's consumer is actually 'server' only when you intend SSR."],"exampleFix":"// before\nbuild: { ssr: true } // input defaults to index.html\n// after\nbuild: { ssr: 'src/entry-server.ts' }","handlingStrategy":"validation","validationCode":"const ssrInput = config.build?.ssr\nif (ssrInput === true || typeof ssrInput === 'string') {\n  const entry = typeof ssrInput === 'string' ? ssrInput : config.build?.rolldownOptions?.input\n  if (typeof entry === 'string' && entry.endsWith('.html')) {\n    throw new Error('SSR build entry must not be an .html file')\n  }\n}","typeGuard":"function isNonHtmlSsrEntry(entry: unknown): boolean {\n  return typeof entry === 'string' && !entry.endsWith('.html')\n}","tryCatchPattern":null,"preventionTips":["Always set build.ssr to a concrete .ts/.js server entry.","Keep a separate entry-server.ts distinct from index.html.","In SSR frameworks, document the required server entry convention."],"tags":["build","ssr","entry","config"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}