vitejs/vite · error · Error
`renderLegacyChunks` and `renderModernChunks` cannot be both
Error message
`renderLegacyChunks` and `renderModernChunks` cannot be both false
What it means
Thrown synchronously when viteLegacyPlugin() is called with both renderLegacyChunks: false and renderModernChunks: false. Since both default to true, this only triggers when a developer explicitly sets both to false. With neither chunk variant being generated, the plugin would have nothing to do, so it fails fast rather than producing a silently empty build.
Source
Thrown at packages/plugin-legacy/src/index.ts:218
function resolveLegacyBuildMinify(
minify: BuildOptions['minify'],
supportsOxc: boolean | undefined,
): BuildOptions['minify'] {
const usesOxc = supportsOxc && (minify === 'oxc' || minify === true)
return usesOxc ? 'oxc' : minify ? 'terser' : false
}
function viteLegacyPlugin(options: Options = {}): Plugin[] {
let config: ResolvedConfig
let targets: Options['targets']
const modernTargets: Options['modernTargets'] =
options.modernTargets || modernTargetsBabel
const genLegacy = options.renderLegacyChunks !== false
const genModern = options.renderModernChunks !== false
if (!genLegacy && !genModern) {
throw new Error(
'`renderLegacyChunks` and `renderModernChunks` cannot be both false',
)
}
const debugFlags = (process.env.DEBUG || '').split(',')
const isDebug =
debugFlags.includes('vite:*') || debugFlags.includes('vite:legacy')
const assumptions = options.assumptions || {}
const facadeToLegacyChunkMap = new Map()
const facadeToLegacyImportMap = new Map<string | null, Rollup.OutputAsset>()
const facadeToLegacyPolyfillMap = new Map()
const facadeToModernPolyfillMap = new Map()
const modernPolyfills = new Set<string>()
const legacyPolyfills = new Set<string>()
// When discovering polyfills in `renderChunk`, the hook may be non-deterministic, so we group the
// modern and legacy polyfills in a sorted chunks map for each rendered outputs before merging them.View on GitHub (pinned to 89620f09af)
Solutions
- If you want to disable the plugin entirely, remove it from the plugins array conditionally instead of setting both flags to false.
- If you only want modern chunks, set renderLegacyChunks: false and leave renderModernChunks at its default (true).
- If you only want legacy chunks, set renderModernChunks: false and leave renderLegacyChunks at its default (true).
Example fix
// before
plugins: [
legacy({ renderLegacyChunks: false, renderModernChunks: false })
]
// after — to fully disable, remove the plugin conditionally
plugins: [
...(shouldUseLegacy ? [legacy()] : [])
] Defensive patterns
Strategy: validation
Validate before calling
function validateLegacyOptions(options) {
const genLegacy = options.renderLegacyChunks !== false
const genModern = options.renderModernChunks !== false
if (!genLegacy && !genModern) {
throw new Error('At least one of renderLegacyChunks or renderModernChunks must be true (or left at default)')
}
}
// call before: validateLegacyOptions(legacyOptions) Type guard
function hasValidRenderOptions(options: Options): boolean {
const genLegacy = options.renderLegacyChunks !== false
const genModern = options.renderModernChunks !== false
return genLegacy || genModern
} Try / catch
try {
if (!hasValidRenderOptions(opts)) {
throw new Error('Invalid plugin-legacy options')
}
plugins.push(legacy(opts))
} catch (e) {
console.error('Failed to configure plugin-legacy:', e.message)
} Prevention
- Never set both renderLegacyChunks and renderModernChunks to false — remove the plugin instead.
- Use a helper function or schema validation (e.g., zod) for plugin options in CI.
- Document your config decisions so other developers don't accidentally disable both.
When it happens
Trigger: Calling legacy({ renderLegacyChunks: false, renderModernChunks: false }) in the plugins array of vite.config.ts. Both options default to true, so this requires explicitly disabling both.
Common situations: A developer wants to disable legacy output temporarily for debugging or CI speed, sets renderLegacyChunks: false, and then also sets renderModernChunks: false thinking the plugin should be fully inert. Or a conditional config spread accidentally merges both to false.
Related errors
- { runtime: "${result.runtime}" } is not supported for assets
- @vitejs/plugin-legacy does not support library mode.
- Invalid environment name "${name}". Environment names must o
- `input` cannot contain glob characters. They are reserved, s
- Required environments configuration were stripped out in the
AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03).
Data as JSON: /data/errors/bf88837022859c96.json.
Report an issue: GitHub.