videojs/video.js · error · Error
Illegal component, "${name}"; ${reason}.
Error message
Illegal component, "${name}"; ${reason}. What it means
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.
Source
Thrown at src/js/component.js:2009
}
const Tech = Component.getComponent('Tech');
// We need to make sure this check is only done if Tech has been registered.
const isTech = Tech && Tech.isTech(ComponentToRegister);
const isComp = Component === ComponentToRegister ||
Component.prototype.isPrototypeOf(ComponentToRegister.prototype);
if (isTech || !isComp) {
let reason;
if (isTech) {
reason = 'techs must be registered using Tech.registerTech()';
} else {
reason = 'must be a Component subclass';
}
throw new Error(`Illegal component, "${name}"; ${reason}.`);
}
name = toTitleCase(name);
if (!Component.components_) {
Component.components_ = {};
}
const Player = Component.getComponent('Player');
if (name === 'Player' && Player && Player.players) {
const players = Player.players;
const playerNames = Object.keys(players);
// If we have players that were disposed, then their name will still be
// in Players.players. So, we must loop through and verify that the value
// for each item is null. This allows registration of the Player component
// after all players have been disposed or before any were created.View on GitHub (pinned to c3a7e0e6d2)
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.
Example fix
// before
class MyThing {} // not a Component
videojs.registerComponent('MyThing', MyThing);
// after
const Component = videojs.getComponent('Component');
class MyThing extends Component {}
videojs.registerComponent('MyThing', MyThing); Defensive patterns
Strategy: type-guard
Validate before calling
const Component = videojs.getComponent('Component');
function isComponentSubclass(Klass) {
return typeof Klass === 'function' &&
(Klass === Component || Component.prototype.isPrototypeOf(Klass.prototype));
}
if (!isComponentSubclass(MyClass)) throw new TypeError('not a Component subclass'); Type guard
const isComponentSubclass = (K) =>
typeof K === 'function' &&
(K === videojs.getComponent('Component') ||
videojs.getComponent('Component').prototype.isPrototypeOf(K.prototype)); Prevention
- Always extend videojs.getComponent('Component').
- Use registerTech for techs, never registerComponent.
- Verify Babel/transpiler config preserves the prototype chain.
When it happens
Trigger: 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.
Common situations: Migrating a tech to look like a component; copy-pasting registration code; ES5-style prototypes that do not properly extend videojs.getComponent('Component').
Related errors
- Illegal component name, "${name}"; must be a non-empty strin
- Component ${componentClassName} does not exist
- currentDimension only accepts width or height value
- No Tech named '${titleTechName}' exists! '${titleTechName}'
- Illegal plugin name, "${name}", must be a string, was ${type
AI-assisted analysis of videojs/video.js@c3a7e0e6d2 (2026-08-13).
Data as JSON: /api/errors/2856e821e60c03fe.
Report an issue: GitHub.