{"record":{"id":"5d0ca2be690900db","repo":"phaserjs/phaser","slug":"node-constructor","errorCode":null,"errorMessage":"node constructor ","messagePattern":"node constructor ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/webgl/renderNodes/RenderNodeManager.js","lineNumber":336,"sourceCode":"            node.setDebug(true);\n        }\n    },\n\n    /**\n     * Add a constructor for a node to the manager.\n     * This will allow the node to be constructed when `getNode` is called.\n     *\n     * @method Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager#addNodeConstructor\n     * @since 4.0.0\n     * @param {string} name - The name of the node.\n     * @param {function} constructor - The constructor for the node.\n     * @throws {Error} Will throw an error if the node constructor already exists.\n     */\n    addNodeConstructor: function (name, constructor)\n    {\n        if (this._nodeConstructors[name])\n        {\n            throw new Error('node constructor ' + name + ' already exists.');\n        }\n        this._nodeConstructors[name] = constructor;\n    },\n\n    /**\n     * Get a node from the manager.\n     *\n     * If the node does not exist, and a constructor is available,\n     * it will be constructed and added to the manager,\n     * then returned.\n     *\n     * @method Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager#getNode\n     * @since 4.0.0\n     * @param {string} name - The name of the node.\n     * @return {?Phaser.Renderer.WebGL.RenderNodes.RenderNode} The node, or null if it does not exist.\n     */\n    getNode: function (name)\n    {","sourceCodeStart":318,"sourceCodeEnd":354,"githubUrl":"https://github.com/phaserjs/phaser/blob/41be1e462bc600064e498cba370bfa8c5c055a22/src/renderer/webgl/renderNodes/RenderNodeManager.js#L318-L354","documentation":"Thrown by RenderNodeManager.addNodeConstructor when a constructor function is registered for a name that already has one in this._nodeConstructors. The constructor registry powers lazy node instantiation via getNode, so a duplicate would create ambiguity about which class to build.","triggerScenarios":"Calling manager.addNodeConstructor(name, ctor) twice with the same name; a plugin registering a constructor whose name collides with a built-in or another plugin's constructor; calling a registration helper on every scene start.","commonSituations":"Plugins that register render nodes on init without checking if already registered; hot module reload re-running the registration code; two libraries both extending the same node slot.","solutions":["Guard registration: if (!manager._nodeConstructors[name]) manager.addNodeConstructor(name, ctor);","Namespace constructor names by plugin/feature.","Move registration to a one-time bootstrap, not per-scene init.","On plugin destroy, only removeNode; do not re-register on re-create."],"exampleFix":"// before\nmanager.addNodeConstructor('MyNode', MyCtor); // throws on second load\n\n// after\nif (!manager._nodeConstructors['MyNode']) {\n  manager.addNodeConstructor('MyNode', MyCtor);\n}","handlingStrategy":"validation","validationCode":"if (!manager._nodeConstructors[name]) { manager.addNodeConstructor(name, ctor); }","typeGuard":"function isCtorRegistered(manager, name) { return Boolean(manager._nodeConstructors && manager._nodeConstructors[name]); }","tryCatchPattern":null,"preventionTips":["Guard registration calls with a presence check.","Move registration to a one-time init.","Use namespaced names to avoid collisions."],"tags":["renderer","webgl","render-node","registry","phaser4"],"backgroundTag":null,"analyzedSha":"41be1e462bc600064e498cba370bfa8c5c055a22","analyzedAt":"2026-08-13T04:23:39.729Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}