{"record":{"id":"bb5af9924fdc6cdd","repo":"angular/angular-cli","slug":"multiple-bundles-have-been-named-the-same-dupl","errorCode":null,"errorMessage":"Multiple bundles have been named the same: '${duplicates.join(`', '`)}'.","messagePattern":"Multiple bundles have been named the same: '(.+?)'\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/angular_devkit/build_angular/src/utils/package-chunk-sort.ts","lineNumber":46,"sourceCode":"    // remove duplicates\n    return [...new Set(entryPoints)].map<EntryPointsType>((f) => [f, false]);\n  };\n\n  const entryPoints: EntryPointsType[] = [\n    ['runtime', !options.isHMREnabled],\n    ['polyfills', true],\n    ...extraEntryPoints(options.styles, 'styles'),\n    ...extraEntryPoints(options.scripts, 'scripts'),\n    ['vendor', true],\n    ['main', true],\n  ];\n\n  const duplicates = entryPoints.filter(\n    ([name]) => entryPoints[0].indexOf(name) !== entryPoints[0].lastIndexOf(name),\n  );\n\n  if (duplicates.length > 0) {\n    throw new Error(`Multiple bundles have been named the same: '${duplicates.join(`', '`)}'.`);\n  }\n\n  return entryPoints;\n}\n","sourceCodeStart":28,"sourceCodeEnd":51,"githubUrl":"https://github.com/angular/angular-cli/blob/bb72145f9ab45aee29f523236b3a25cd0813a841/packages/angular_devkit/build_angular/src/utils/package-chunk-sort.ts#L28-L51","documentation":"generateEntryPoints assembles the initial webpack entry-point list (runtime, polyfills, styles, scripts, vendor, main) from injectable styles/scripts in the build options. If any bundle name collides, the duplicates check fires this error so the produced HTML does not contain ambiguous, overwriting script tags. In the checked-in code the duplicate scan only compares against the first entry (runtime) via entryPoints[0], so it only reliably catches a name colliding with 'runtime', though the intent is to reject any duplicate bundle name.","triggerScenarios":"Building with angular.json styles or scripts entries whose computed bundleName (glob basename, or explicit bundleName via normalizeExtraEntryPoints) collides with a reserved entry name — 'runtime', 'polyfills', 'styles', 'scripts', 'vendor', 'main', or another extra entry — and inject: true.","commonSituations":"Adding a script like node_modules/x/main.js (bundleName 'main') or a style named 'styles.css' from a nonstandard path, after upgrades where default bundle naming changed (e.g. extra entries now default to 'scripts'/'styles'), or two extra entries resolving to the same bundleName.","solutions":["Set an explicit unique \"bundleName\" on the conflicting scripts/styles entry in angular.json.","Rename the source file so its basename does not collide with reserved bundle names (main, runtime, polyfills, styles, scripts, vendor).","If two extra entries collide with each other, merge them or give each a distinct bundleName.","Verify inject: false for entries that should not participate in the initial entry list."],"exampleFix":"// before (angular.json)\n\"scripts\": [{ \"input\": \"node_modules/some-lib/main.js\", \"inject\": true }]\n// after\n\"scripts\": [{ \"input\": \"node_modules/some-lib/main.js\", \"inject\": true, \"bundleName\": \"some-lib\" }]","handlingStrategy":"validation","validationCode":"// Detect colliding bundle names before building\nconst RESERVED = ['runtime', 'polyfills', 'styles', 'scripts', 'vendor', 'main'];\nfunction findBundleNameCollisions(scripts = [], styles = []) {\n  const names = [];\n  for (const e of [...scripts, ...styles]) {\n    if (e.inject === false) continue;\n    const name = e.bundleName ??\n      require('path').basename(e.input.split('*').pop().replace(/\\.[jt]sx?$/, '').replace(/\\.(css|scss|sass|less|styl)$/, ''), '.js');\n    names.push(name);\n  }\n  return [...new Set(names.filter(n => RESERVED.includes(n) || names.indexOf(n) !== names.lastIndexOf(n)))];\n}","typeGuard":null,"tryCatchPattern":"try {\n  const entryPoints = generateEntryPoints(options);\n  return entryPoints;\n} catch (err) {\n  if (/^Multiple bundles have been named the same:/.test(err?.message ?? '')) {\n    console.error('Assign a unique \"bundleName\" to the conflicting styles/scripts entry in angular.json.');\n  } else throw err;\n}","preventionTips":["Give every injected scripts/styles entry an explicit unique \"bundleName\" in angular.json.","Avoid naming extra entry source files main.*, styles.*, scripts.*, vendor.*, runtime.* or polyfills.*.","Diff bundle names after Angular CLI upgrades, since default bundle naming for extra entries has changed across versions."],"tags":["angular-cli","webpack","duplicate-bundle-names","configuration"],"backgroundTag":"duplicate-bundle-name","analyzedSha":"bb72145f9ab45aee29f523236b3a25cd0813a841","analyzedAt":"2026-08-30T02:47:34.745Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}