{"id":"d03ff8403c9c79ea","repo":"vitejs/vite","slug":"no-corresponding-legacy-entry-chunk-found-for-ht","errorCode":null,"errorMessage":"No corresponding legacy entry chunk found for ${htmlFilename}","messagePattern":"No corresponding legacy entry chunk found for (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/plugin-legacy/src/index.ts","lineNumber":850,"sourceCode":"          tag: 'script',\n          attrs: {\n            nomodule: genModern,\n            crossorigin: true,\n            // we set the entry path on the element as an attribute so that the\n            // script content will stay consistent - which allows using a constant\n            // hash value for CSP.\n            id: legacyEntryId,\n            'data-src': toAssetPathFromHtml(\n              legacyEntryFilename,\n              chunk.facadeModuleId!,\n              config,\n            ),\n          },\n          children: systemJSInlineCode,\n          injectTo: 'body',\n        })\n      } else {\n        throw new Error(\n          `No corresponding legacy entry chunk found for ${htmlFilename}`,\n        )\n      }\n\n      // 6. inject dynamic import fallback entry\n      if (legacyPolyfillFilename && legacyEntryFilename && genModern) {\n        tags.push({\n          tag: 'script',\n          attrs: { type: 'module' },\n          children: detectModernBrowserCode,\n          injectTo: 'head',\n        })\n        tags.push({\n          tag: 'script',\n          attrs: { type: 'module' },\n          children: dynamicFallbackInlineCode,\n          injectTo: 'head',\n        })","sourceCodeStart":832,"sourceCodeEnd":868,"githubUrl":"https://github.com/vitejs/vite/blob/89620f09afcfef6b35e7bb8660132ab5b4d0cd3b/packages/plugin-legacy/src/index.ts#L832-L868","documentation":"Thrown in transformIndexHtml when the legacy entry chunk mapping is missing for the current HTML entry. The facadeToLegacyChunkMap is populated when the legacy bundle's transformIndexHtml runs (line 725), recording each facadeModuleId to its legacy chunk fileName. If the modern bundle's HTML transform runs and can't find the corresponding legacy entry, it means the legacy bundle was either not generated or its HTML transform didn't record the entry before the modern one needed it.","triggerScenarios":"genLegacy is true but the legacy bundle generation was skipped or failed silently. Can occur when renderLegacyChunks is true but the legacy output configuration is not properly generated (e.g., due to custom rolldownOptions.output manipulation), or when plugin hook ordering causes the modern HTML transform to run before the legacy one records its chunk.","commonSituations":"Custom output configurations that interfere with plugin-legacy's dual-output injection (lines 547-559). Using build.rollupOptions.output as a function or in unexpected shapes. Plugin ordering conflicts where another enforce:'post' plugin runs transformIndexHtml before plugin-legacy's legacy pass.","solutions":["Avoid customizing build.rolldownOptions.output when using plugin-legacy — the plugin injects its own legacy output configuration.","Check that no other enforce:'post' plugin with transformIndexHtml runs before plugin-legacy's legacy HTML pass.","Update plugin-legacy and Vite to compatible versions.","If the issue persists, file a bug with a minimal multi-output reproduction."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure no conflicting output customizations when using plugin-legacy\nfunction validateLegacyOutputConfig(config) {\n  const output = config.build?.rollupOptions?.output\n  if (output && !Array.isArray(output) && typeof output !== 'string') {\n    if (output.format && output.format !== 'esm') {\n      console.warn('plugin-legacy expects esm output; custom format may break entry mapping')\n    }\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await build({ plugins: [legacy()], ...minimalConfig })\n} catch (e) {\n  if (e.message.includes('No corresponding legacy entry chunk')) {\n    console.error('Legacy entry mapping failed. Simplify output config and check plugin order.')\n  }\n  throw e\n}","preventionTips":["Don't customize build.rolldownOptions.output when using plugin-legacy — it injects its own outputs.","Audit enforce:'post' plugins for transformIndexHtml hooks that might run before plugin-legacy.","Keep plugin-legacy last in the plugins array among post-enforce plugins."],"tags":["plugin-legacy","html","legacy-entry","plugin-ordering"],"analyzedSha":"89620f09afcfef6b35e7bb8660132ab5b4d0cd3b","analyzedAt":"2026-08-03T19:28:02.920Z","schemaVersion":2}