BabylonJS/Babylon.js · error · Error

"Shaders may have no more than 1 main input"

Error message

"Shaders may have no more than 1 main input"

What it means

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.

Source

Thrown at packages/dev/smartFilters/src/utils/buildTools/shaderConverter.ts:291

        }
        const regex = new RegExp(`(?<=\\W+)${symbol}(?=\\W+)`, "gs");
        fragmentShaderWithRenamedSymbols = fragmentShaderWithRenamedSymbols.replace(regex, DecorateSymbol(symbol));
    }
    log(`${symbolsToDecorate.length} symbol(s) renamed`);

    // Extract all the uniforms
    const finalUniforms = [...fragmentShaderWithRenamedSymbols.matchAll(/^\s*(uniform\s.*)/gm)].map((match) => match[1]);

    // Extract all the consts
    const finalConsts = [...fragmentShaderWithRenamedSymbols.matchAll(/^\s*(const\s.*)/gm)].map((match) => match[1]);

    // Extract all the defines
    const finalDefines = [...fragmentShaderWithRenamedSymbols.matchAll(new RegExp(GetDefineRegExString, GetDefineRegExOptions))].map((match) => match[0]);

    // Find the main input
    const mainInputs = [...fragmentShaderWithRenamedSymbols.matchAll(/\S*uniform.*\s(\w*);\s*\/\/\s*main/gm)].map((match) => match[1]);
    if (mainInputs.length > 1) {
        throw new Error("Shaders may have no more than 1 main input");
    }
    const mainInputTexture = mainInputs[0];

    // Extract all the functions
    const { extractedFunctions, mainFunctionName } = ExtractFunctions(fragmentShaderWithRenamedSymbols);

    const shaderCode: ShaderCode = {
        uniform: finalUniforms.join("\n"),
        mainFunctionName,
        mainInputTexture,
        functions: extractedFunctions,
        defines: finalDefines,
    };

    if (finalConsts.length > 0) {
        shaderCode.const = finalConsts.join("\n");
    }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Keep exactly one uniform with the `// main` comment; remove the comment from all others.
  2. For additional textures, declare them as plain uniforms (they become extra texture connection points without the marker).
  3. Search the shader for `// main` and ensure it appears only once next to a uniform.

Example fix

// before
uniform sampler2D inputA; // main
uniform sampler2D inputB; // main
// after
uniform sampler2D inputA; // main
uniform sampler2D inputB;
Defensive patterns

Strategy: validation

Validate before calling

const mainCount = [...shader.matchAll(/\S*uniform.*\s(\w*);\s*\/\/\s*main/gm)].length;
if (mainCount > 1) throw new Error(`Shader declares ${mainCount} main inputs; exactly 1 required`);

Type guard

function hasSingleMainInput(shader: string): boolean {
  return [...shader.matchAll(/\S*uniform.*\s(\w*);\s*\/\/\s*main/gm)].length <= 1;
}

Try / catch

try {
  const info = ParseFragmentShader(blockName, namespace, shader);
} catch (e) {
  if (e instanceof Error && e.message === "Shaders may have no more than 1 main input") {
    // strip the extra '// main' comments before retrying
  } else throw e;
}

Prevention

When it happens

Trigger: ParseFragmentShader on a fragment shader containing two uniforms each suffixed with `// main`, e.g. `uniform sampler2D inputA; // main` and `uniform sampler2D inputB; // main`.

Common situations: 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.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/98d903afe7eba32c. Report an issue: GitHub.