BabylonJS/Babylon.js · error · Error

${error}

Error message

${error}

What it means

Thrown when the WebGL program fails to LINK after both shaders compiled individually. _finalizePipelineContext calls context.getProgramInfoLog(program) and throws the raw link log, storing it in pipelineContext.programLinkError. Compilation of each shader succeeded, but glLinkProgram found incompatibilities between them.

Source

Thrown at packages/dev/core/src/Engines/thinEngine.functions.ts:245

            if (log) {
                pipelineContext.vertexCompilationError = log;
                throw new Error("VERTEX SHADER " + log);
            }
        }

        // Fragment
        if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
            const log = gl.getShaderInfoLog(fragmentShader);
            if (log) {
                pipelineContext.fragmentCompilationError = log;
                throw new Error("FRAGMENT SHADER " + log);
            }
        }

        const error = context.getProgramInfoLog(program);
        if (error) {
            pipelineContext.programLinkError = error;
            throw new Error(error);
        }
    }

    if (/*this.*/ validateShaderPrograms) {
        context.validateProgram(program);
        const validated = context.getProgramParameter(program, context.VALIDATE_STATUS);

        if (!validated) {
            const error = context.getProgramInfoLog(program);
            if (error) {
                pipelineContext.programValidationError = error;
                throw new Error(error);
            }
        }
    }

    context.deleteShader(vertexShader);
    context.deleteShader(fragmentShader);

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Read the thrown log — it typically says which varying/attribute is mismatched or which limit was exceeded
  2. Make varying/in-out declarations match exactly (name, type, precision) between vertex and fragment shaders
  3. Reduce the number of varyings/attributes if the log mentions limits
  4. Inspect pipelineContext.programLinkError for the stored log when handling the error

Example fix

// before
vertex: `varying vec2 vUv; ...` fragment: `varying vec2 UV; ...` // name mismatch
// after
vertex: `varying vec2 vUv; ...` fragment: `varying vec2 vUv; ...`
Defensive patterns

Strategy: validation

Validate before calling

function checkVaryingsMatch(vertexSrc: string, fragmentSrc: string): string[] {
  const decl = /(?:varying|out)\s+\w+\s+(\w+)\s*;/g;
  const outs = new Set<string>(); let m;
  while ((m = decl.exec(vertexSrc))) outs.add(m[1]);
  const ins = /(?:varying|in)\s+\w+\s+(\w+)\s*;/g;
  const missing: string[] = [];
  while ((m = ins.exec(fragmentSrc))) outs.delete(m[1]);
  return [...outs]; // varyings declared in vertex but missing in fragment
}

Type guard

function isLinkError(e: unknown): e is Error & { pipelineProgramLinkError?: string } {
  return e instanceof Error && !e.message.startsWith('FRAGMENT SHADER');
}

Try / catch

try {
  engine.createEffect(...);
} catch (e) {
  const msg = (e as Error).message;
  if (!msg.startsWith('FRAGMENT SHADER') && !msg.startsWith('VERTEX')) {
    console.error('Program link failed:', msg); // raw link log
  }
}

Prevention

When it happens

Trigger: Vertex and fragment shaders that compile alone but don't link: varying/in variables with mismatched names, types, or precision between stages; an out variable in vertex shader never declared as in/out in fragment; too many attributes or varyings exceeding GPU limits.

Common situations: Hand-written ShaderMaterial where vertex and fragment strings were edited independently; renaming a varying in one stage only; using 'varying' in WebGL2 without #version 300 es handling; exceeding maxVaryings on low-end/mobile GPUs.

Related errors


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