{"record":{"id":"c1fc4f409fdde646","repo":"BabylonJS/Babylon.js","slug":"no-function-name-found-in-shader-code","errorCode":null,"errorMessage":"\"No function name found in shader code\"","messagePattern":"\"No function name found in shader code\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts","lineNumber":357,"sourceCode":"    mainFunctionName: string;\r\n} {\r\n    const extractedFunctions: ShaderFunction[] = [];\r\n    let mainFunctionName: string | undefined;\r\n    let pos = 0;\r\n\r\n    const getFunctionHeaderRegEx = new RegExp(GetFunctionHeaderRegExString, GetFunctionHeaderRegExOptions);\r\n\r\n    while (pos < fragment.length) {\r\n        // Match the next available function header in the fragment code\r\n        getFunctionHeaderRegEx.lastIndex = pos;\r\n        const match = getFunctionHeaderRegEx.exec(fragment);\r\n        if (!match) {\r\n            break;\r\n        }\r\n\r\n        const functionName = match[1];\r\n        if (!functionName) {\r\n            throw new Error(\"No function name found in shader code\");\r\n        }\r\n\r\n        const functionParams = match[2] || \"\";\r\n\r\n        // Store start index of the function definition\r\n        const startIndex = match.index;\r\n\r\n        // Balance braces to find end of function, starting just after the opening `{`\r\n        let endIndex = match.index + match[0].length;\r\n        let depth = 1;\r\n        while (depth > 0 && endIndex < fragment.length) {\r\n            if (fragment[endIndex] === \"{\") {\r\n                depth++;\r\n            } else if (fragment[endIndex] === \"}\") {\r\n                depth--;\r\n            }\r\n            endIndex++;\r\n        }\r","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts#L339-L375","documentation":"ExtractFunctions scans the shader with GetFunctionHeaderRegEx; a header match whose capture group 1 (the function name) is empty means the regex matched something that looks like a function header but has no identifier. The parser cannot register a nameless function, so it throws. This is rare — usually a symptom of unusual syntax near a function definition.","triggerScenarios":"ExtractFunctions (via ParseFragmentShader) on shader code where the function-header regex matches a construct with an empty name capture, e.g. malformed syntax like `void () { }`, macro-expanded code that erased the identifier, or regex edge cases with anonymous-looking constructs.","commonSituations":"Shaders generated by codegen/templates with broken placeholders (`void %s(...)` unresolved); heavy macro usage that confuses the header regex; typos like a missing function name after the return type.","solutions":["Inspect the shader near the reported location and give the function a proper name: `void doWork() { ... }`.","Resolve/expand any preprocessor macros that might hide the function name before conversion.","Simplify exotic syntax around function declarations (no attributes/annotations directly confusing the header pattern)."],"exampleFix":"// before\nvoid () {\n  gl_FragColor = vec4(1.0);\n}\n// after\nvoid fillColor() {\n  gl_FragColor = vec4(1.0);\n}","handlingStrategy":"validation","validationCode":"const headers = [...shader.matchAll(/\\b\\w+\\s+(\\w*)\\s*\\([^)]*\\)\\s*\\{/g)];\nif (headers.some(m => !m[1])) throw new Error(\"Shader contains a function header with an empty name\");","typeGuard":"function allFunctionsNamed(shader: string): boolean {\n  return [...shader.matchAll(/\\b\\w+\\s+(\\w*)\\s*\\([^)]*\\)\\s*\\{/g)].every(m => m[1].length > 0);\n}","tryCatchPattern":"try {\n  const info = ParseFragmentShader(blockName, namespace, shader);\n} catch (e) {\n  if (e instanceof Error && e.message === \"No function name found in shader code\") {\n    // locate the unnamed function near the reported position and name it\n  } else throw e;\n}","preventionTips":["Always name functions; never emit placeholder/anonymous headers from codegen.","Expand or remove macros around function declarations before conversion.","Run a GLSL syntax validator on shaders as a pre-build step."],"tags":["shader","parsing","glsl","functions"],"backgroundTag":"shader-function-parse-failed","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}