pbakaus/impeccable · error · Error

shader compile failed: ${info}

Error message

shader compile failed: ${info}

What it means

compileShader throws this when a WebGL shader fails to compile: gl.getShaderParameter(sh, gl.COMPILE_STATUS) is false. It includes the driver's gl.getShaderInfoLog output so the offending GLSL line/syntax is identifiable, and deletes the failed shader before throwing.

Source

Thrown at skill/scripts/live-browser.js:8511

    let r = 0, g = 0, b = 0, n = 0;
    for (const [px, py] of pts) {
      const cx = Math.max(0, Math.min(W - 1, Math.round(px)));
      const cy = Math.max(0, Math.min(H - 1, Math.round(py)));
      const d = ctx.getImageData(cx, cy, 1, 1).data;
      if (d[3] === 0) continue; // outside the ancestor's paint
      r += d[0]; g += d[1]; b += d[2]; n++;
    }
    return n ? [r / n / 255, g / n / 255, b / n / 255] : null;
  }

  function compileShader(gl, type, source) {
    const sh = gl.createShader(type);
    gl.shaderSource(sh, source);
    gl.compileShader(sh);
    if (!gl.getShaderParameter(sh, gl.COMPILE_STATUS)) {
      const info = gl.getShaderInfoLog(sh);
      gl.deleteShader(sh);
      throw new Error('shader compile failed: ' + info);
    }
    return sh;
  }

  function positionShaderOverlay() {
    if (!shaderState) return;
    const anchor = resolveBarAnchor();
    if (!anchor) return;
    const r = anchor.getBoundingClientRect();
    Object.assign(shaderState.canvas.style, {
      top: r.top + 'px', left: r.left + 'px',
      width: r.width + 'px', height: r.height + 'px',
    });
  }

  /** Drop a shader node no shaderState owns (an abandoned construction). */
  function removeStrayShaderNode() {
    const stray = uiGetById(PREFIX + '-shader');

View on GitHub (pinned to 2bc2879276)

Solutions

  1. Read the info log appended to the message — it names the GLSL line and error
  2. Validate the shader source for GLSL ES compatibility (avoid ES 3.00 syntax on a WebGL1 context)
  3. Test on another machine/browser to isolate driver-specific compile failures
  4. Check that context creation requested the needed attributes (antialias, precision) and that precision qualifiers are declared

Example fix

// before
const info = gl.getShaderInfoLog(sh);
throw new Error('shader compile failed: ' + info);
// after
const info = gl.getShaderInfoLog(sh);
console.error('shader source:\n' + source.split('\n').map((l,i)=>(i+1)+': '+l).join('\n'));
throw new Error('shader compile failed: ' + info);
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: compile in a scratch context before committing the effect
const test = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(test, SHADER_FS); gl.compileShader(test);
if (!gl.getShaderParameter(test, gl.COMPILE_STATUS)) console.warn(gl.getShaderInfoLog(test));

Try / catch

try {
  initShaderOverlay();
} catch (err) {
  if (err.message.startsWith('shader compile failed')) {
    console.error(err.message); // includes the GLSL info log
    showToast('GPU shader unsupported on this device; falling back to CSS.');
  }
}

Prevention

When it happens

Trigger: The shader source (e.g. the halftone SHADER_FS/vertex shader) contains GLSL that the GPU/driver rejects — syntax errors, unsupported GLSL version/extension, or uniform/varying mismatches on a specific machine's driver.

Common situations: Users on old or buggy GPU drivers rejecting otherwise-valid GLSL; headless or software renderers (SwiftShader limits); a code change introducing a GLSL typo or an ES 3.0 construct on an ES 1.0 context.

Related errors


AI-assisted analysis of pbakaus/impeccable@2bc2879276 (2026-09-08). Data as JSON: /api/errors/b73ca51743f69eaf. Report an issue: GitHub.