vitejs/vite · error · Error

No corresponding legacy polyfill chunk found for ${htmlFilen

Error message

No corresponding legacy polyfill chunk found for ${htmlFilename}

What it means

Thrown in transformIndexHtml when legacy polyfills were collected (legacyPolyfills.size > 0) but no legacy polyfill chunk was registered for the current HTML entry. Analogous to the modern polyfill error (index 5) but for the legacy polyfill set. The facadeToLegacyPolyfillMap should have been populated during buildPolyfillChunk in generateBundle, but the entry's facadeModuleId has no corresponding entry.

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 89620f09af)

Solutions

  1. If polyfills is set to true (default auto-detect), try explicitly listing them: polyfills: ['es.array.flat', 'es.promise'].
  2. Ensure rollupOptions.input HTML entries resolve to actual file paths that match facadeModuleId.
  3. Check that no other plugin strips or rewrites facadeModuleId on entry chunks.
  4. Update plugin-legacy to the latest version.

Example fix

// before
legacy() // auto-detect polyfills, fails on unusual entries
// after
legacy({ polyfills: ['es.array.flat', 'es.promise', 'regenerator-runtime'] })
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate polyfill configuration for multi-page setups
function validatePolyfillConfig(options, input) {
  if (options.polyfills === true || options.polyfills === undefined) {
    // auto-detect mode — ensure entries are standard HTML files
    const entries = typeof input === 'object' ? Object.values(input) : [input]
    for (const e of entries) {
      if (!String(e).endsWith('.html')) {
        console.warn(`Auto polyfill detection may fail for non-HTML entry: ${e}`)
      }
    }
  }
}

Type guard

function hasExplicitLegacyPolyfills(options: Options): boolean {
  return Array.isArray(options.polyfills)
}

Try / catch

try {
  await build({
    plugins: [legacy({ polyfills: ['es.promise', 'es.array.flat'] })]
  })
} catch (e) {
  if (e.message.includes('No corresponding legacy polyfill chunk')) {
    console.error('Switch to explicit polyfills array or check entry resolution')
  }
  throw e
}

Prevention

When it happens

Trigger: Same as the modern polyfill variant but for legacy polyfills: auto-detected or explicitly configured legacy polyfills exist, but the facadeModuleId of the HTML entry chunk doesn't match any chunk iterated in buildPolyfillChunk's bundle scan. Common with custom entry resolution or virtual HTML entry modules.

Common situations: Multi-page apps, custom plugins modifying entry module IDs, or MPA configs where HTML files are resolved through custom logic. Also seen when externalSystemJS is misconfigured alongside polyfill options.

Related errors


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