mrdoob/three.js · error · Error

THREE.WGSLNodeFunction: Function is not a WGSL code.

Error message

THREE.WGSLNodeFunction: Function is not a WGSL code.

What it means

Thrown by the WGSLNodeFunction parser when the supplied source string does not match the WGSL function-declaration regex (`^[fn]*\s*(name)?\s*(...)\s*[->]?\s*returnType`). The parser expects a single WGSL function signature with a parameter list and a return type; anything else (a GLSL snippet, a bare expression, a struct, malformed syntax) fails to parse.

Source

Thrown at src/renderers/webgpu/nodes/WGSLNodeFunction.js:142

		const blockCode = source.substring( declaration[ 0 ].length );
		const outputType = declaration[ 3 ] || 'void';

		const name = declaration[ 1 ] !== undefined ? declaration[ 1 ] : '';
		const type = wgslTypeLib[ outputType ] || outputType;

		return {
			type,
			inputs,
			name,
			inputsCode,
			blockCode,
			outputType
		};

	} else {

		throw new Error( 'THREE.WGSLNodeFunction: Function is not a WGSL code.' );

	}

};

/**
 * This class represents a WSL node function.
 *
 * @augments NodeFunction
 */
class WGSLNodeFunction extends NodeFunction {

	/**
	 * Constructs a new WGSL node function.
	 *
	 * @param {string} source - The WGSL source.
	 */
	constructor( source ) {

View on GitHub (pinned to da05705fa3)

Solutions

  1. Ensure the source is a single WGSL function: `fn myFn(a: f32) -> f32 { return a; }`.
  2. Use the GLSL equivalent builder (glslFn) for GLSL source instead of wgslFn.
  3. Extract only the function you want parsed; don't pass structs, globals, or multiple functions.
  4. Validate the string starts with `fn` (or matches the declaration regex) before constructing WGSLNodeFunction.

Example fix

// before - passing GLSL to a WGSL builder
const fn = wgslFn(`float myFn(float a) { return a; }`); // throws

// after - valid WGSL
const fn = wgslFn(`fn myFn(a: f32) -> f32 { return a; }`);
Defensive patterns

Strategy: try-catch

Validate before calling

const WGSL_FN_RE = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\->]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i;
function assertWgslFunction(source) {
  if (!WGSL_FN_RE.test(source.trim())) throw new Error('Source is not a WGSL function declaration');
}

Type guard

function looksLikeWgslFunction(source) {
  const re = /^[fn]*\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)\s*[\->]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i;
  return re.test(String(source).trim());
}

Try / catch

try {
  const fn = wgslFn(source);
} catch (e) {
  if (/Function is not a WGSL code/.test(e.message)) { /* switch to glslFn for GLSL, or rewrite source as `fn name(...) -> ret { ... }` */ }
  else throw e;
}

Prevention

When it happens

Trigger: Passing non-WGSL code (e.g. GLSL) to a WGSLNodeFunction / wgslFn builder. Passing a struct declaration, a statement, or a malformed function. Using wgslFn with a template string that doesn't begin with a valid function signature.

Common situations: Mixing up WGSL and GLSL node-function builders (e.g. calling wgslFn with glsl source). Copying a snippet missing the `fn name(...) -> ret` prefix. Passing a multi-statement WGSL module instead of a single function. Whitespace/character issues that break the anchored regex.

Related errors


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