vitejs/vite · critical · Error

Internal @vitejs/plugin-legacy error: discovered polyfills s

Error message

Internal @vitejs/plugin-legacy error: discovered polyfills should exist

What it means

An internal assertion in plugin-legacy's generateBundle hook. The plugin maintains a WeakMap (outputToChunkFileNameToPolyfills) keyed by output options, initialized to null in renderStart (line 457) and populated during renderChunk. If generateBundle fires and the WeakMap entry for the current output options is null or missing, it means the plugin's hooks ran out of order or renderStart was never called for this output. This indicates a bug in plugin-legacy or a plugin ordering conflict with another plugin that manipulates outputs.

Source

Thrown at packages/plugin-legacy/src/index.ts:365

        )
      }
    },
  }

  let supportsLegacyOxcMinification: boolean | undefined
  const legacyGenerateBundlePlugin: Plugin = {
    name: 'vite:legacy-generate-polyfill-chunk',
    apply: 'build',

    async generateBundle(opts, bundle) {
      if (config.build.ssr) {
        return
      }

      const chunkFileNameToPolyfills =
        outputToChunkFileNameToPolyfills.get(opts)
      if (chunkFileNameToPolyfills == null) {
        throw new Error(
          'Internal @vitejs/plugin-legacy error: discovered polyfills should exist',
        )
      }

      if (!isLegacyBundle(bundle)) {
        // Merge discovered modern polyfills to `modernPolyfills`
        for (const { modern } of chunkFileNameToPolyfills.values()) {
          modern.forEach((p) => modernPolyfills.add(p))
        }
        if (!modernPolyfills.size) {
          return
        }
        if (isDebug) {
          console.log(
            `[@vitejs/plugin-legacy] modern polyfills:`,
            modernPolyfills,
          )
        }

View on GitHub (pinned to 89620f09af)

Solutions

  1. Check for other plugins in your config that modify rollupOptions.output and ensure they run after plugin-legacy or don't alter output object identity.
  2. Update @vitejs/plugin-legacy and vite to matching compatible versions.
  3. If reproducible, file a bug report with the minimal config that triggers it — this is an internal invariant violation.
  4. Temporarily simplify your output configuration to a single output object to see if the issue is multi-output related.
Defensive patterns

Strategy: try-catch

Try / catch

// This is an internal error — wrap the build to fail gracefully and collect diagnostics
try {
  await build({ plugins: [legacy()], ...config })
} catch (e) {
  if (e.message.includes('Internal @vitejs/plugin-legacy error')) {
    console.error('plugin-legacy internal error. This is likely a bug.')
    console.error('Please report at https://github.com/vitejs/vite/issues with your config.')
    process.exit(1)
  }
  throw e
}

Prevention

When it happens

Trigger: Another Vite/Rollup plugin reorders or clones output options objects after renderStart but before generateBundle, causing the WeakMap reference to no longer match. Can also occur with custom multi-output configurations where the output options object identity changes between hooks.

Common situations: Using a third-party plugin that modifies rollupOptions.output in its own configResolved or renderStart, or using plugin-legacy with experimental/unstable Vite features that alter the output pipeline. Encountered during version upgrades where plugin-legacy's internal hook ordering assumptions break.

Related errors


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