vitejs/vite · error · Error

`renderLegacyChunks` and `renderModernChunks` cannot be…

Error message

`renderLegacyChunks` and `renderModernChunks` cannot be both false

What it means

plugin-legacy has two independent toggles: `renderLegacyChunks` (default true) controls whether SystemJS-based legacy bundles are emitted, and `renderModernChunks` (default true) controls whether modern bundles/polyfills are emitted. Setting BOTH to false means the plugin would emit no output at all, which is an invalid configuration, so the plugin rejects it eagerly in `viteLegacyPlugin()`.

Solutions

  1. Remove the `legacy()` plugin from the Vite plugins array entirely if you want no legacy/modern processing.
  2. Keep at least one of the two flags at its default `true` (leave `renderModernChunks` unset while setting only `renderLegacyChunks: false`, or vice versa).
  3. If you only want polyfills without legacy SystemJS output, set `renderLegacyChunks: false` and provide `modernPolyfills` while leaving `renderModernChunks` at its default.

Example fix

// before
legacy({ renderLegacyChunks: false, renderModernChunks: false }),
// after - just drop the plugin
// (remove the `legacy(...)` line from plugins)
Defensive patterns

Strategy: validation

Validate before calling

function validateLegacyOptions(opts: { renderLegacyChunks?: boolean; renderModernChunks?: boolean }) {
  if (opts.renderLegacyChunks === false && opts.renderModernChunks === false) {
    throw new Error('At least one of renderLegacyChunks/renderModernChunks must be true (or both left default).')
  }
}

Type guard

function isLegalLegacyOptions(o: unknown): boolean {
  if (!o || typeof o !== 'object') return true
  const { renderLegacyChunks, renderModernChunks } = o as any
  return !(renderLegacyChunks === false && renderModernChunks === false)
}

Prevention

When it happens

Trigger: Passing `{ renderLegacyChunks: false, renderModernChunks: false }` to `legacy()` in the Vite plugins array. This can happen when trying to use plugin-legacy purely for its polyfill detection while disabling both chunk kinds, or when conditionally computing flags that both evaluate to false.

Common situations: Trying to 'disable' plugin-legacy at runtime by flipping both flags to false instead of removing the plugin from the array. Copying an options object and toggling the wrong flag. Migrating between plugin versions where flag semantics changed.

Related errors


AI-assisted analysis of vitejs/vite@b4d66fee14 (2026-08-11). Data as JSON: /api/errors/bf88837022859c96. Report an issue: GitHub.

Appendix: 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 b4d66fee14)