{"record":{"id":"0858ce47047e69c2","repo":"angular/angular.js","slug":"too-many-components-found","errorCode":null,"errorMessage":"Too many components found","messagePattern":"Too many components found","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ngMock/angular-mocks.js","lineNumber":2550,"sourceCode":" * @return {Object} Instance of requested controller.\n */\nangular.mock.$ComponentControllerProvider = ['$compileProvider',\n    function ComponentControllerProvider($compileProvider) {\n  this.$get = ['$controller','$injector', '$rootScope', function($controller, $injector, $rootScope) {\n    return function $componentController(componentName, locals, bindings, ident) {\n      // get all directives associated to the component name\n      var directives = $injector.get(componentName + 'Directive');\n      // look for those directives that are components\n      var candidateDirectives = directives.filter(function(directiveInfo) {\n        // components have controller, controllerAs and restrict:'E'\n        return directiveInfo.controller && directiveInfo.controllerAs && directiveInfo.restrict === 'E';\n      });\n      // check if valid directives found\n      if (candidateDirectives.length === 0) {\n        throw new Error('No component found');\n      }\n      if (candidateDirectives.length > 1) {\n        throw new Error('Too many components found');\n      }\n      // get the info of the component\n      var directiveInfo = candidateDirectives[0];\n      // create a scope if needed\n      locals = locals || {};\n      locals.$scope = locals.$scope || $rootScope.$new(true);\n      return $controller(directiveInfo.controller, locals, bindings, ident || directiveInfo.controllerAs);\n    };\n  }];\n}];\n\n\n/**\n * @ngdoc module\n * @name ngMock\n * @packageName angular-mocks\n * @description\n *","sourceCodeStart":2532,"sourceCodeEnd":2568,"githubUrl":"https://github.com/angular/angular.js/blob/d8f77817eb5c98dec5317bc3756d1ea1812bcfbe/src/ngMock/angular-mocks.js#L2532-L2568","documentation":"$componentController filters the directives registered under a name to component-shaped ones (controller + controllerAs + restrict 'E'). If MORE than one definition survives — multiple loaded modules (including transitively pulled-in ones) each define a directive/component with that name — the mock cannot decide which controller to instantiate and throws 'Too many components found'.","triggerScenarios":"Two modules both loaded in the test define the same name as component/directive (e.g., your app's 'tabs' and a UI library's 'tabs'); a component plus a hand-written directive with the same name that also has controller, controllerAs and restrict 'E'; accidentally registering the same component in two modules during a refactor/rename.","commonSituations":"Loading a third-party module that collides with an in-house component name; test bundles loading both app.module and a feature module that re-exports the same component; duplicated directive definitions left behind after renaming.","solutions":["Rename one of the colliding components/directives so the name is unique across all loaded modules.","Stop loading the module that redefines the name in this test's beforeEach(module(...)) chain.","If you only need the controller logic, bypass the ambiguity: instantiate a specific controller with $controller('RatingCtrl', ...) instead of $componentController."],"exampleFix":"// before\n// app module\nangular.module('app').component('tabs', {controller: AppTabsCtrl, controllerAs: '$ctrl'});\n// third-party module, also loaded in the test\nangular.module('ui.lib').component('tabs', {controller: LibTabsCtrl, controllerAs: '$ctrl'});\n$componentController('tabs'); // throws: Too many components found\n\n// after\nangular.module('app').component('appTabs', {controller: AppTabsCtrl, controllerAs: '$ctrl'});\n// update the template <app-tabs> and the call:\n$componentController('appTabs');","handlingStrategy":"validation","validationCode":"// Detect name collisions before instantiating\ninject(function($injector) {\n  var candidates = $injector.get('tabs' + 'Directive').filter(function(d) {\n    return d.controller && d.controllerAs && d.restrict === 'E';\n  });\n  if (candidates.length !== 1) {\n    throw new Error('Expected exactly 1 component named tabs, found ' + candidates.length);\n  }\n});","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefix in-house component names (appTabs vs tabs) to avoid third-party collisions.","Audit loaded modules when adding a UI library: search for duplicate .component/.directive names.","Delete old definitions after renames instead of leaving both registered."],"tags":["angular-mocks","component","duplicate","testing","injector"],"backgroundTag":"duplicate-directive-registration","analyzedSha":"d8f77817eb5c98dec5317bc3756d1ea1812bcfbe","analyzedAt":"2026-08-21T20:36:31.651Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}