{"record":{"id":"ec610a5812401155","repo":"mrdoob/three.js","slug":"three-functionnode-function-is-not-a-glsl-code","errorCode":null,"errorMessage":"THREE.FunctionNode: Function is not a GLSL code.","messagePattern":"THREE\\.FunctionNode: Function is not a GLSL code\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/nodes/parsers/GLSLNodeFunction.js","lineNumber":98,"sourceCode":"\t\tconst type = declaration[ 2 ];\n\n\t\tconst precision = declaration[ 1 ] !== undefined ? declaration[ 1 ] : '';\n\n\t\tconst headerCode = pragmaMainIndex !== - 1 ? source.slice( 0, pragmaMainIndex ) : '';\n\n\t\treturn {\n\t\t\ttype,\n\t\t\tinputs,\n\t\t\tname,\n\t\t\tprecision,\n\t\t\tinputsCode,\n\t\t\tblockCode,\n\t\t\theaderCode\n\t\t};\n\n\t} else {\n\n\t\tthrow new Error( 'THREE.FunctionNode: Function is not a GLSL code.' );\n\n\t}\n\n};\n\n/**\n * This class represents a GLSL node function.\n *\n * @augments NodeFunction\n */\nclass GLSLNodeFunction extends NodeFunction {\n\n\t/**\n\t * Constructs a new GLSL node function.\n\t *\n\t * @param {string} source - The GLSL source.\n\t */\n\tconstructor( source ) {","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/mrdoob/three.js/blob/da05705fa31f02710c19772a2aa70c7454807f0c/src/nodes/parsers/GLSLNodeFunction.js#L80-L116","documentation":"Thrown by the GLSL node-function parser when the source string does not begin with a valid GLSL function declaration. The regex requires `[precision?] returnType name?(params)` with exactly 5 capture groups; anything that fails to match (missing return type, missing parens, no params delimiter, JS/TS code, or WGSL) reaches the else branch.","triggerScenarios":"Passing JavaScript/TypeScript or WGSL source to `Fn(..., { parser: GLSLNodeFunction })`; a GLSL string that starts with a struct/layout declaration instead of the function signature; malformed/empty string; missing `#pragma main` placement that leaves the signature unparsable.","commonSituations":"Authoring `Fn` with inline GLSL but forgetting the return type or parameter list; mixing TSL and raw GLSL incorrectly; copy-pasting GLSL that has leading comments/newlines the regex cannot skip; version change in parser strictness.","solutions":["Ensure the GLSL string starts with a function signature like `float myFn( float x ) { ... }`.","Use the default TSL parser for TSL/JS function bodies; only pass true GLSL to the GLSL parser.","Strip leading comments/whitespace/structs before the function signature, or place them after `#pragma main`."],"exampleFix":"// before\nconst f = Fn( `struct S{...}; float run(float x){return x;}` );\n\n// after\nconst f = Fn( `float run( float x ) { return x; }` );","handlingStrategy":"validation","validationCode":"const GLSL_FN_RE = /^\\s*(highp|mediump|lowp)?\\s*([a-z_0-9]+)\\s*([a-z_0-9]+)?\\s*\\(([\\s\\S]*?)\\)/i;\nfunction isValidGlslFn( src ) {\n  const m = ( src.indexOf( '#pragma main' ) !== -1 ? src.slice( src.indexOf( '#pragma main' ) + 11 ) : src ).match( GLSL_FN_RE );\n  return m !== null && m.length === 5;\n}","typeGuard":"const looksLikeGlslFunction = ( src ) => isValidGlslFn( src );","tryCatchPattern":null,"preventionTips":["Start GLSL Fn strings with a typed function signature.","Use the default TSL parser for TSL/JS bodies; reserve the GLSL parser for real GLSL.","Strip leading structs/comments or move them after #pragma main."],"tags":["glsl","function-node","parser","tsl"],"backgroundTag":null,"analyzedSha":"da05705fa31f02710c19772a2aa70c7454807f0c","analyzedAt":"2026-08-12T22:51:37.160Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}