{"record":{"id":"98d903afe7eba32c","repo":"BabylonJS/Babylon.js","slug":"shaders-may-have-no-more-than-1-main-input","errorCode":null,"errorMessage":"\"Shaders may have no more than 1 main input\"","messagePattern":"\"Shaders may have no more than 1 main input\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts","lineNumber":291,"sourceCode":"        }\r\n        const regex = new RegExp(`(?<=\\\\W+)${symbol}(?=\\\\W+)`, \"gs\");\r\n        fragmentShaderWithRenamedSymbols = fragmentShaderWithRenamedSymbols.replace(regex, DecorateSymbol(symbol));\r\n    }\r\n    log(`${symbolsToDecorate.length} symbol(s) renamed`);\r\n\r\n    // Extract all the uniforms\r\n    const finalUniforms = [...fragmentShaderWithRenamedSymbols.matchAll(/^\\s*(uniform\\s.*)/gm)].map((match) => match[1]);\r\n\r\n    // Extract all the consts\r\n    const finalConsts = [...fragmentShaderWithRenamedSymbols.matchAll(/^\\s*(const\\s.*)/gm)].map((match) => match[1]);\r\n\r\n    // Extract all the defines\r\n    const finalDefines = [...fragmentShaderWithRenamedSymbols.matchAll(new RegExp(GetDefineRegExString, GetDefineRegExOptions))].map((match) => match[0]);\r\n\r\n    // Find the main input\r\n    const mainInputs = [...fragmentShaderWithRenamedSymbols.matchAll(/\\S*uniform.*\\s(\\w*);\\s*\\/\\/\\s*main/gm)].map((match) => match[1]);\r\n    if (mainInputs.length > 1) {\r\n        throw new Error(\"Shaders may have no more than 1 main input\");\r\n    }\r\n    const mainInputTexture = mainInputs[0];\r\n\r\n    // Extract all the functions\r\n    const { extractedFunctions, mainFunctionName } = ExtractFunctions(fragmentShaderWithRenamedSymbols);\r\n\r\n    const shaderCode: ShaderCode = {\r\n        uniform: finalUniforms.join(\"\\n\"),\r\n        mainFunctionName,\r\n        mainInputTexture,\r\n        functions: extractedFunctions,\r\n        defines: finalDefines,\r\n    };\r\n\r\n    if (finalConsts.length > 0) {\r\n        shaderCode.const = finalConsts.join(\"\\n\");\r\n    }\r\n\r","sourceCodeStart":273,"sourceCodeEnd":309,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts#L273-L309","documentation":"A custom block shader must have exactly one main input: a uniform marked with a `// main` comment, which receives the source texture. If the shader marks two or more uniforms with `// main`, this error is thrown. Zero main inputs is allowed here (handled elsewhere), but more than one is ambiguous.","triggerScenarios":"ParseFragmentShader on a fragment shader containing two uniforms each suffixed with `// main`, e.g. `uniform sampler2D inputA; // main` and `uniform sampler2D inputB; // main`.","commonSituations":"Copying an existing main-input line to add a second texture input and forgetting to drop the `// main` marker; combining two shader templates each with their own main input; duplicate-paste of the uniform block.","solutions":["Keep exactly one uniform with the `// main` comment; remove the comment from all others.","For additional textures, declare them as plain uniforms (they become extra texture connection points without the marker).","Search the shader for `// main` and ensure it appears only once next to a uniform."],"exampleFix":"// before\nuniform sampler2D inputA; // main\nuniform sampler2D inputB; // main\n// after\nuniform sampler2D inputA; // main\nuniform sampler2D inputB;","handlingStrategy":"validation","validationCode":"const mainCount = [...shader.matchAll(/\\S*uniform.*\\s(\\w*);\\s*\\/\\/\\s*main/gm)].length;\nif (mainCount > 1) throw new Error(`Shader declares ${mainCount} main inputs; exactly 1 required`);","typeGuard":"function hasSingleMainInput(shader: string): boolean {\n  return [...shader.matchAll(/\\S*uniform.*\\s(\\w*);\\s*\\/\\/\\s*main/gm)].length <= 1;\n}","tryCatchPattern":"try {\n  const info = ParseFragmentShader(blockName, namespace, shader);\n} catch (e) {\n  if (e instanceof Error && e.message === \"Shaders may have no more than 1 main input\") {\n    // strip the extra '// main' comments before retrying\n  } else throw e;\n}","preventionTips":["Search the shader for '// main' before committing; keep exactly one occurrence on a uniform.","Add extra texture inputs as plain uniforms without the marker.","Add a CI check that greps shader assets for multiple '// main' markers."],"tags":["shader","glsl","smart-filters","configuration"],"backgroundTag":"multiple-main-inputs","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}