pbakaus/impeccable · error · Error
program link failed: ${gl.getProgramInfoLog(program)}
Error message
program link failed: ${gl.getProgramInfoLog(program)} What it means
Thrown when the WebGL program built from the compiled vertex + fragment shaders fails to link: gl.getProgramParameter(program, gl.LINK_STATUS) is false. The message embeds gl.getProgramInfoLog(program), which typically reports mismatched varyings/uniforms or resource limits between the two shader stages.
Source
Thrown at skill/scripts/live-browser.js:8619
|| canvas.getContext('experimental-webgl');
if (!gl) {
// WebGL unavailable: use the captured bitmap as a background overlay so
// the user still sees something meaningful during generation.
if (abandoned(canvas, null)) return;
showShaderBitmapFallback(canvas, blob);
return;
}
let program, texture;
try {
const vs = compileShader(gl, gl.VERTEX_SHADER, SHADER_VS);
const fs = compileShader(gl, gl.FRAGMENT_SHADER, SHADER_FS);
program = gl.createProgram();
gl.attachShader(program, vs);
gl.attachShader(program, fs);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
throw new Error('program link failed: ' + gl.getProgramInfoLog(program));
}
// Full-screen quad
const buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1, -1, 0, 1,
1, -1, 1, 1,
-1, 1, 0, 0,
-1, 1, 0, 0,
1, -1, 1, 1,
1, 1, 1, 0,
]), gl.STATIC_DRAW);
const posLoc = gl.getAttribLocation(program, 'a_position');
const uvLoc = gl.getAttribLocation(program, 'a_uv');
gl.enableVertexAttribArray(posLoc);
gl.vertexAttribPointer(posLoc, 2, gl.FLOAT, false, 16, 0);
gl.enableVertexAttribArray(uvLoc);
gl.vertexAttribPointer(uvLoc, 2, gl.FLOAT, false, 16, 8);View on GitHub (pinned to 2bc2879276)
Solutions
- Read the program info log in the message — it names the linking incompatibility
- Ensure varyings/attributes used in the fragment shader are declared identically in the vertex shader
- Confirm both shaders compiled (compileShader would have thrown first) and were attached before linkProgram
- Revert recent GLSL edits and re-apply incrementally to find the mismatching declaration
Defensive patterns
Strategy: try-catch
Validate before calling
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
console.warn(gl.getProgramInfoLog(program));
} Try / catch
try {
program = createShaderProgram(gl, SHADER_VS, SHADER_FS);
} catch (err) {
if (err.message.startsWith('program link failed')) {
console.error(err.message);
showToast('Shader program unavailable on this GPU; disabling the effect.');
}
} Prevention
- Keep varying declarations identical (name and type) across vertex and fragment shaders
- Link only after both shaders report COMPILE_STATUS
- After editing GLSL, re-read getProgramInfoLog — link errors surface stage mismatches compile misses
- Validate on target devices; link failures are often driver/resource-limit specific
When it happens
Trigger: attachShader + linkProgram on a valid context where the vertex and fragment shaders are incompatible (e.g. a varying written in the vertex shader but declared with a different type, or not declared, in the fragment shader), or the program exceeds driver limits.
Common situations: Editing SHADER_FS or the vertex shader so their varying/interface declarations diverge; drivers that reject implicit conversions; running on devices with restrictive shader resource limits.
Related errors
- shader compile failed: ${info}
- [impeccable] shader setup failed:
- [impeccable] shader bitmap decode failed:
- No painted ancestor for Svelte shader proxy
AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08).
Data as JSON: /api/errors/fbd4102db395f023.
Report an issue: GitHub.