mrdoob/three.js · error · Error

THREE.TSL: Node element ${ name } is not a function

Error message

THREE.TSL: Node element ${ name } is not a function

What it means

Thrown by TSLCore.addMethodChaining() when registering a TSL method whose `nodeElement` is not a function. This is an internal registration API used to wire method chaining onto Node.prototype. A non-function value (undefined, an object, a string) means the chaining call `nodeElement(...)` would fail, so it is rejected upfront.

Source

Thrown at src/nodes/tsl/TSLCore.js:31

let currentStack = null;

const NodeElements = new Map();

// Extend Node Class for TSL using prototype

export function addMethodChaining( name, nodeElement ) {

	// No require StackTrace because this is internal API

	if ( NodeElements.has( name ) ) {

		warn( `TSL: Redefinition of method chaining '${ name }'.` );
		return;

	}

	if ( typeof nodeElement !== 'function' ) throw new Error( `THREE.TSL: Node element ${ name } is not a function` );

	NodeElements.set( name, nodeElement );

	if ( name !== 'assign' ) {

		// Changing Node prototype to add method chaining

		Node.prototype[ name ] = function ( ...params ) {

			//if ( name === 'toVarIntent' ) return this;

			return this.isStackNode ? this.addToStack( nodeElement( ...params ) ) : nodeElement( this, ...params );

		};

		// Adding assign method chaining

		Node.prototype[ name + 'Assign' ] = function ( ...params ) {

View on GitHub (pinned to da05705fa3)

Solutions

  1. Pass a function (typically a `nodeProxy(SomeNode)` factory) as the second argument.
  2. Verify the imported symbol exists and is a function before registering it.
  3. Check the import path and export name against the current Three.js version.

Example fix

// before
import { SomeNode } from './SomeNode.js';
addMethodChaining( 'some', SomeNode ); // SomeNode is a class, not a factory

// after
import { SomeNode } from './SomeNode.js';
addMethodChaining( 'some', nodeProxy( SomeNode ) );
Defensive patterns

Strategy: type-guard

Validate before calling

function registerMethod( name, nodeElement ) {
  if ( typeof nodeElement !== 'function' ) {
    throw new TypeError( `Cannot register '${ name }': nodeElement is not a function` );
  }
  addMethodChaining( name, nodeElement );
}

Type guard

const isNodeElementFactory = ( v ) => typeof v === 'function';

Prevention

When it happens

Trigger: A plugin/extension calling `addMethodChaining(name, value)` with an undefined import (wrong/default import), an object instead of a factory function, or a typo'd variable; a bundler tree-shaking a named export to undefined.

Common situations: Writing a TSL extension that registers custom methods; importing a node element from the wrong path so it resolves to undefined; version mismatch where an export was renamed or removed.

Related errors


AI-assisted analysis of mrdoob/three.js@da05705fa3 (2026-08-12). Data as JSON: /api/errors/d88f242a2706a449. Report an issue: GitHub.