{"record":{"id":"53843b60df6fdaa0","repo":"mrdoob/three.js","slug":"three-nodelibrary-node-class-nodeclass-name","errorCode":null,"errorMessage":"THREE.NodeLibrary: Node class ${ nodeClass.name } is not a class.","messagePattern":"THREE\\.NodeLibrary: Node class (.+?) is not a class\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderers/common/nodes/NodeLibrary.js","lineNumber":164,"sourceCode":"\t}\n\n\t/**\n\t * Adds a node class definition for the given type to the provided type library.\n\t *\n\t * @param {Node.constructor} nodeClass - The node class definition.\n\t * @param {number|string} type - The object type.\n\t * @param {Map<number|string,Node.constructor>} library - The type library.\n\t */\n\taddType( nodeClass, type, library ) {\n\n\t\tif ( library.has( type ) ) {\n\n\t\t\twarn( `Redefinition of node ${ type }` );\n\t\t\treturn;\n\n\t\t}\n\n\t\tif ( typeof nodeClass !== 'function' ) throw new Error( `THREE.NodeLibrary: Node class ${ nodeClass.name } is not a class.` );\n\t\tif ( typeof type === 'function' || typeof type === 'object' ) throw new Error( `THREE.NodeLibrary: Base class ${ type } is not a class.` );\n\n\t\tlibrary.set( type, nodeClass );\n\n\t}\n\n\t/**\n\t * Adds a node class definition for the given class definition to the provided type library.\n\t *\n\t * @param {Node.constructor} nodeClass - The node class definition.\n\t * @param {Node.constructor} baseClass - The class definition.\n\t * @param {WeakMap<Node.constructor, Node.constructor>} library - The type library.\n\t */\n\taddClass( nodeClass, baseClass, library ) {\n\n\t\tif ( library.has( baseClass ) ) {\n\n\t\t\twarn( `Redefinition of node ${ baseClass.name }` );","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/renderers/common/nodes/NodeLibrary.js#L146-L182","documentation":"Thrown by NodeLibrary.addType() when the supplied nodeClass argument is not a function (i.e. not a JS class/constructor). The library maps a type id to a Node constructor, so a non-callable value (undefined, an instance, a plain object, a number) is a programming error. Note: if nodeClass is undefined/null, reading `nodeClass.name` in the message can itself throw — pass a real class.","triggerScenarios":"Calling `nodeLibrary.addType(someValue, type, library)` where someValue is undefined (e.g. a failed import), an instance rather than a class, or a primitive. Triggered indirectly by addMaterialNode/addLightNode paths that route through addType.","commonSituations":"Circular import that evaluated to undefined at registration time. Passing `new MyNode()` instead of `MyNode`. Plugin/extension registration done before the node class module finished loading. Bundler tree-shaking removing a side-effect-only class export.","solutions":["Ensure the first argument is the class itself (a function), not an instance: `addType(MyNodeClass, type, library)`.","Check for failed imports — log `nodeClass` before registering; if undefined, fix the import path or circular dependency.","Reorder module imports so node class modules are fully evaluated before addType is called.","Mark side-effect-bearing registration modules as sideEffects: false cautiously, or import them eagerly."],"exampleFix":"// before\nimport { MyNode } from './MyNode.js'; // MyNode is undefined due to circular import\nlibrary.addType(MyNode, 42, library.materialNodes); // throws\n\n// after\n// fix the circular import so MyNode is defined, then:\nlibrary.addType(MyNode, 42, library.materialNodes);","handlingStrategy":"type-guard","validationCode":"function safeAddType(nodeClass, type, library) {\n  if (typeof nodeClass !== 'function') {\n    throw new TypeError(`addType expected a class, got ${typeof nodeClass}`);\n  }\n  library.addType(nodeClass, type, library);\n}","typeGuard":"function isNodeClass(v) {\n  return typeof v === 'function' && /^(class |function )/.test(v.toString());\n}","tryCatchPattern":"try {\n  library.addType(nodeClass, type, library);\n} catch (e) {\n  if (/Node class .* is not a class/.test(e.message)) { console.error('Registration skipped: nodeClass is', nodeClass); /* fix import then re-register */ }\n  else throw e;\n}","preventionTips":["Log every value you pass to addType during development to catch undefined imports early.","Break circular imports by lazy-importing node classes inside the registration function.","Add a typeof guard in your registration wrapper to fail with a clearer message than the library."],"tags":["nodes","node-library","registration","type-error","import"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}