{"record":{"id":"2856e821e60c03fe","repo":"videojs/video.js","slug":"illegal-component-name-reason","errorCode":null,"errorMessage":"Illegal component, \"${name}\"; ${reason}.","messagePattern":"Illegal component, \"(.+?)\"; (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/js/component.js","lineNumber":2009,"sourceCode":"    }\n\n    const Tech = Component.getComponent('Tech');\n\n    // We need to make sure this check is only done if Tech has been registered.\n    const isTech = Tech && Tech.isTech(ComponentToRegister);\n    const isComp = Component === ComponentToRegister ||\n      Component.prototype.isPrototypeOf(ComponentToRegister.prototype);\n\n    if (isTech || !isComp) {\n      let reason;\n\n      if (isTech) {\n        reason = 'techs must be registered using Tech.registerTech()';\n      } else {\n        reason = 'must be a Component subclass';\n      }\n\n      throw new Error(`Illegal component, \"${name}\"; ${reason}.`);\n    }\n\n    name = toTitleCase(name);\n\n    if (!Component.components_) {\n      Component.components_ = {};\n    }\n\n    const Player = Component.getComponent('Player');\n\n    if (name === 'Player' && Player && Player.players) {\n      const players = Player.players;\n      const playerNames = Object.keys(players);\n\n      // If we have players that were disposed, then their name will still be\n      // in Players.players. So, we must loop through and verify that the value\n      // for each item is null. This allows registration of the Player component\n      // after all players have been disposed or before any were created.","sourceCodeStart":1991,"sourceCodeEnd":2027,"githubUrl":"https://github.com/videojs/video.js/blob/c3a7e0e6d20cf5400c9afbee29965fe4dff393c2/src/js/component.js#L1991-L2027","documentation":"registerComponent rejects classes that are not subclasses of Component (or Component itself) and explicitly deflects Tech classes, which must go through Tech.registerTech(). This keeps the component registry type-coherent; mixing in arbitrary constructors would break addChild instantiation and isPrototypeOf checks elsewhere.","triggerScenarios":"Calling registerComponent('X', SomePlainClass) where SomePlainClass does not extend Component; calling registerComponent('X', Html5) where Html5 is a Tech; passing a function/POJO instead of a class.","commonSituations":"Migrating a tech to look like a component; copy-pasting registration code; ES5-style prototypes that do not properly extend videojs.getComponent('Component').","solutions":["For a real component: class MyComp extends videojs.getComponent('Component') { ... } then registerComponent('MyComp', MyComp).","For a Tech, use videojs.registerTech(name, TechClass) instead.","Ensure transpilation (Babel) is configured so extends correctly sets up the prototype chain that isPrototypeOf checks."],"exampleFix":"// before\nclass MyThing {} // not a Component\nvideojs.registerComponent('MyThing', MyThing);\n// after\nconst Component = videojs.getComponent('Component');\nclass MyThing extends Component {}\nvideojs.registerComponent('MyThing', MyThing);","handlingStrategy":"type-guard","validationCode":"const Component = videojs.getComponent('Component');\nfunction isComponentSubclass(Klass) {\n  return typeof Klass === 'function' &&\n    (Klass === Component || Component.prototype.isPrototypeOf(Klass.prototype));\n}\nif (!isComponentSubclass(MyClass)) throw new TypeError('not a Component subclass');","typeGuard":"const isComponentSubclass = (K) =>\n  typeof K === 'function' &&\n  (K === videojs.getComponent('Component') ||\n   videojs.getComponent('Component').prototype.isPrototypeOf(K.prototype));","tryCatchPattern":null,"preventionTips":["Always extend videojs.getComponent('Component').","Use registerTech for techs, never registerComponent.","Verify Babel/transpiler config preserves the prototype chain."],"tags":["component","registry","tech","validation"],"backgroundTag":null,"analyzedSha":"c3a7e0e6d20cf5400c9afbee29965fe4dff393c2","analyzedAt":"2026-08-13T04:20:15.471Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}