phaserjs/phaser · error · Error
node
Error message
node
What it means
Thrown by RenderNodeManager.addNode when a node is registered under a name that already exists in this._nodes. Names are unique keys into the render-graph registry because getNode looks nodes up by name and the system assumes one instance per name.
Source
Thrown at src/renderer/webgl/renderNodes/RenderNodeManager.js:310
* @default null
*/
this.currentDebugNode = null;
},
/**
* Add a node to the manager.
*
* @method Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager#addNode
* @since 4.0.0
* @param {string} name - The name of the node.
* @param {Phaser.Renderer.WebGL.RenderNodes.RenderNode} node - The node to add.
* @throws {Error} Will throw an error if the node already exists.
*/
addNode: function (name, node)
{
if (this._nodes[name])
{
throw new Error('node ' + name + ' already exists.');
}
this._nodes[name] = node;
// If a node is somehow added during a debug render pass,
// ensure that it is also set to debug.
if (this.debug)
{
node.setDebug(true);
}
},
/**
* Add a constructor for a node to the manager.
* This will allow the node to be constructed when `getNode` is called.
*
* @method Phaser.Renderer.WebGL.RenderNodes.RenderNodeManager#addNodeConstructor
* @since 4.0.0
* @param {string} name - The name of the node.View on GitHub (pinned to 41be1e462b)
Solutions
- Namespace your node names (e.g. 'MyPlugin.BatchHandler') to avoid collisions with built-ins and other plugins.
- Before adding, check manager._nodes[name] or guard with a removeNode call if re-registering is expected.
- On teardown/hot-reload, remove previously added nodes before re-adding them.
- Use addNodeConstructor + getNode (lazy construction) instead of eagerly adding duplicate instances.
Example fix
// before
manager.addNode('Batch', nodeA);
manager.addNode('Batch', nodeB); // throws
// after
if (!manager._nodes['Batch']) {
manager.addNode('Batch', nodeA);
} else {
manager.removeNode('Batch');
manager.addNode('Batch', nodeB);
} Defensive patterns
Strategy: validation
Validate before calling
if (manager._nodes[name]) { /* skip or remove+re-add */ } else { manager.addNode(name, node); } Type guard
function isNodeRegistered(manager, name) { return Boolean(manager._nodes && manager._nodes[name]); } Try / catch
try { manager.addNode(name, node); } catch (e) { if (/already exists/.test(e.message)) { manager.removeNode(name); manager.addNode(name, node); } else throw e; } Prevention
- Namespace node names by plugin/owner.
- Register once at bootstrap, not per scene.
- Remove nodes on plugin destroy.
When it happens
Trigger: Calling manager.addNode(name, node) twice with the same name string; adding a node whose name collides with a built-in node (e.g. 'BatchHandlerQuad'); a plugin or scene adding a node that another plugin already registered.
Common situations: Two plugins registering custom render nodes with the same name; hot-reloading a scene/plugin that re-adds its nodes without tearing down the old ones; reusing a generic name like 'batch' across modules.
Related errors
- node constructor
- BatchHandler must have a name
- BatchHandlerStrip: Vertex count exceeds maximum per batch (
- BaseFilterShader: No fragment shader source provided and no
- Color attachments must have the same dimensions
AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13).
Data as JSON: /api/errors/45ccb99bab085edf.
Report an issue: GitHub.