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

  1. If you want to disable the plugin entirely, remove it from the plugins array conditionally instead of setting both flags to false.
  2. If you only want modern chunks, set renderLegacyChunks: false and leave renderModernChunks at its default (true).
  3. 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

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


AI-assisted analysis of vitejs/vite@89620f09af (2026-08-03). Data as JSON: /data/errors/bf88837022859c96.json. Report an issue: GitHub.