vitejs/vite · error · Error

No corresponding modern polyfill chunk found for

Error message

No corresponding modern polyfill chunk found for ${htmlFilename}

What it means

During `transformIndexHtml`, if `genModern` is true and `modernPolyfills.size > 0` but `facadeToModernPolyfillMap.get(chunk.facadeModuleId)` is undefined for an HTML entry, plugin-legacy cannot find the generated modern-polyfill chunk that should be injected as `<script type=module>`. This indicates the polyfill chunk was expected (polyfills were configured/discovered) but was never recorded for that HTML facade, usually because `renderChunk` did not run the polyfill discovery for that output.

Solutions

  1. Ensure every HTML entry goes through the standard build pipeline so `renderChunk` populates `facadeToModernPolyfillMap`.
  2. If you set `modernPolyfills` explicitly, verify the polyfill chunk is actually emitted (check `dist/assets` for the polyfill file).
  3. Avoid custom `output`/manual chunking that strips or renames the polyfill chunk away from the plugin's discovery.
  4. Upgrade @vitejs/plugin-legacy and vite to matching supported versions.

Example fix

// before: modernPolyfills set but a custom output config drops the polyfill chunk
build: {
  rollupOptions: { output: { /* aggressive manualChunks that excludes polyfills */ } },
},
plugins: [legacy({ modernPolyfills: true })],
// after: let plugin-legacy own the polyfill chunk, remove manual chunk overrides
plugins: [legacy({ modernPolyfills: true })],
Defensive patterns

Strategy: validation

Validate before calling

// Pre-build sanity: ensure modernPolyfills config is self-consistent
function checkModernPolyfillsConfig(opts: { renderModernChunks?: boolean; modernPolyfills?: unknown }) {
  const genModern = opts.renderModernChunks !== false
  const hasPolyfills = Array.isArray(opts.modernPolyfills) ? opts.modernPolyfills.length > 0 : opts.modernPolyfills === true
  if (!genModern && hasPolyfills) {
    throw new Error('modernPolyfills set but renderModernChunks is false - polyfill chunk will be missing')
  }
}

Try / catch

try {
  await vite.build(cfg)
} catch (e) {
  if (e instanceof Error && /No corresponding modern polyfill chunk/.test(e.message)) {
    // remove custom rollup output overrides & rebuild, or drop modernPolyfills
  } else throw e
}

Prevention

When it happens

Trigger: Configuring `modernPolyfills` (or relying on automatic discovery) and building with multiple HTML entries or a custom `renderChunk`/output configuration where the modern polyfill bundle is not produced for a particular entry. Also seen when `renderModernChunks` is true but the modern polyfill set is populated yet the chunk map stays empty (e.g., manual bundle manipulation).

Common situations: Multi-page apps where one HTML entry lacks a corresponding modern polyfill chunk. Customizing rollup output in a way that skips the legacy plugin's `renderChunk`. Inconsistent plugin versions between vite and plugin-legacy.

Related errors


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

Appendix: source

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

        const modernPolyfillFilename = facadeToModernPolyfillMap.get(
          chunk.facadeModuleId,
        )

        if (modernPolyfillFilename) {
          tags.push({
            tag: 'script',
            attrs: {
              type: 'module',
              crossorigin: true,
              src: toAssetPathFromHtml(
                modernPolyfillFilename,
                chunk.facadeModuleId!,
                config,
              ),
            },
          })
        } else if (modernPolyfills.size) {
          throw new Error(
            `No corresponding modern polyfill chunk found for ${htmlFilename}`,
          )
        }
      }

      if (!genLegacy) {
        return { html, tags }
      }

      // 2. inject importmaps
      if (config.environments.client.build.chunkImportMap) {
        const importMap = facadeToLegacyImportMap.get(chunk.facadeModuleId)!
        const decoder = new TextDecoder()
        tags.push({
          tag: 'script',
          attrs: { type: 'systemjs-importmap' },
          children:
            typeof importMap.source === 'string'

View on GitHub (pinned to b4d66fee14)