{"record":{"id":"0cf854bab23f25df","repo":"videojs/video.js","slug":"can-not-register-player-component-after-player-has","errorCode":null,"errorMessage":"Can not register Player component after player has been created.","messagePattern":"Can not register Player component after player has been created\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/js/component.js","lineNumber":2031,"sourceCode":"\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.\n      if (players && playerNames.length > 0) {\n        for (let i = 0; i < playerNames.length; i++) {\n          if (players[playerNames[i]] !== null) {\n            throw new Error('Can not register Player component after player has been created.');\n          }\n        }\n      }\n    }\n\n    Component.components_[name] = ComponentToRegister;\n    Component.components_[toLowerCase(name)] = ComponentToRegister;\n\n    return ComponentToRegister;\n  }\n\n  /**\n   * Get a `Component` based on the name it was registered with.\n   *\n   * @param {string} name\n   *        The Name of the component to get.\n   *\n   * @return {typeof Component}","sourceCodeStart":2013,"sourceCodeEnd":2049,"githubUrl":"https://github.com/videojs/video.js/blob/c3a7e0e6d20cf5400c9afbee29965fe4dff393c2/src/js/component.js#L2013-L2049","documentation":"The Player component class is special — it holds the live Player.players map of active instances. Re-registering it after instances exist would orphan those instances and break videojs('id') lookups, so video.js forbids it while any non-null player is alive. You may only re-register Player before creation or after every player has been disposed.","triggerScenarios":"Calling videojs.registerComponent('Player', CustomPlayer) after at least one videojs instance has been created and not disposed.","commonSituations":"Hot-module reloading in dev that re-runs the Player registration; lazy-loading a custom Player subclass; upgrading video.js without disposing old players first.","solutions":["Register your custom Player subclass BEFORE any videojs() instances are created (typically at module load).","Dispose all existing players first: videojs.getAllPlayers().forEach(p => p.dispose()), then register.","Guard against double-registration in HMR by tracking whether the custom Player was already registered."],"exampleFix":"// before\nconst p = videojs('vid');\nvideojs.registerComponent('Player', MyPlayer); // throws\n// after\nvideojs.registerComponent('Player', MyPlayer); // before any instance\nconst p = videojs('vid');","handlingStrategy":"validation","validationCode":"function registerPlayerSafe(Klass) {\n  const players = videojs.players || {};\n  const alive = Object.keys(players).some(k => players[k] !== null);\n  if (alive) throw new Error('dispose all players before re-registering Player');\n  videojs.registerComponent('Player', Klass);\n}","typeGuard":"const noAlivePlayers = () =>\n  Object.keys(videojs.players || {}).every(k => videojs.players[k] === null);","tryCatchPattern":null,"preventionTips":["Register custom Player subclasses once, before any instance.","In HMR, track registration and skip on reload.","Dispose players explicitly in teardown."],"tags":["player","registry","lifecycle","hmr"],"backgroundTag":null,"analyzedSha":"c3a7e0e6d20cf5400c9afbee29965fe4dff393c2","analyzedAt":"2026-08-13T04:20:15.471Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}