vitejs/vite · error · Error

No corresponding legacy polyfill chunk found for

Error message

No corresponding legacy polyfill chunk found for ${htmlFilename}

What it means

Symmetric to the modern case: when `genLegacy` is true and `legacyPolyfills.size > 0` but `facadeToLegacyPolyfillMap.get(chunk.facadeModuleId)` is undefined for an HTML entry, plugin-legacy cannot inject the `<script nomodule>` legacy polyfill chunk. The polyfill set was populated (configured or discovered) but no chunk was recorded for that facade.

Solutions

  1. Confirm the legacy polyfill chunk exists in the build output (`dist/assets/polyfills-legacy-*.js`).
  2. Remove custom `manualChunks`/`output` overrides that interfere with plugin-legacy's polyfill chunk generation.
  3. If you don't need legacy polyfills, clear `polyfills`/`additionalLegacyPolyfills` so `legacyPolyfills.size` is 0.
  4. Align vite and @vitejs/plugin-legacy versions.

Example fix

// before
plugins: [legacy({ polyfills: ['es.array.includes'], modernPolyfills: [] })],
build: { rollupOptions: { output: { entryFileNames: '[name].js' /* strips polyfill naming */ } } },
// after - keep default output handling
plugins: [legacy({ polyfills: ['es.array.includes'] })],
Defensive patterns

Strategy: validation

Validate before calling

function checkLegacyPolyfillsConfig(opts: { renderLegacyChunks?: boolean; polyfills?: unknown; additionalLegacyPolyfills?: unknown }) {
  const genLegacy = opts.renderLegacyChunks !== false
  const has = (Array.isArray(opts.polyfills) ? opts.polyfills.length : !!opts.polyfills)
    || (Array.isArray(opts.additionalLegacyPolyfills) ? opts.additionalLegacyPolyfills.length : !!opts.additionalLegacyPolyfills)
  if (!genLegacy && has) {
    throw new Error('Legacy polyfills configured but renderLegacyChunks is false - chunk will be missing')
  }
}

Try / catch

try {
  await vite.build(cfg)
} catch (e) {
  if (e instanceof Error && /No corresponding legacy polyfill chunk/.test(e.message)) {
    // stop interfering with the legacy polyfill chunk generation, then rebuild
  } else throw e
}

Prevention

When it happens

Trigger: Setting `polyfills`/`additionalLegacyPolyfills` (so `legacyPolyfills` is non-empty) while the legacy polyfill chunk is not produced or not associated with the current HTML entry during `transformIndexHtml`.

Common situations: Custom `renderChunk`/output config that bypasses polyfill discovery for the legacy output. Multi-page builds where an entry's legacy polyfill chunk is missing. Mixing manually-cleared polyfill sets with enabled legacy generation.

Related errors


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

Appendix: source

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

        chunk.facadeModuleId,
      )
      if (legacyPolyfillFilename) {
        tags.push({
          tag: 'script',
          attrs: {
            nomodule: genModern,
            crossorigin: true,
            id: legacyPolyfillId,
            src: toAssetPathFromHtml(
              legacyPolyfillFilename,
              chunk.facadeModuleId!,
              config,
            ),
          },
          injectTo: 'body',
        })
      } else if (legacyPolyfills.size) {
        throw new Error(
          `No corresponding legacy polyfill chunk found for ${htmlFilename}`,
        )
      }

      // 5. inject legacy entry
      const legacyEntryFilename = facadeToLegacyChunkMap.get(
        chunk.facadeModuleId,
      )
      if (legacyEntryFilename) {
        // `assets/foo.js` means importing "named register" in SystemJS
        tags.push({
          tag: 'script',
          attrs: {
            nomodule: genModern,
            crossorigin: true,
            // we set the entry path on the element as an attribute so that the
            // script content will stay consistent - which allows using a constant
            // hash value for CSP.

View on GitHub (pinned to b4d66fee14)