fabricjs/fabric.js · error · FabricError

Fragment shader compile error for ${this.type}: ${gl.getShad

Error message

Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(
          fragmentShader,
        )}

What it means

Fabric's BaseFilter.createProgram compiles each filter's fragment shader (the GLSL that implements the filter effect) and checks gl.getShaderParameter(COMPILE_STATUS). A false status throws this error, embedding the filter type and the GLSL compiler info log so you can see the exact failing line. It's the fragment-stage counterpart of the vertex compile error and is the one you'll hit from bad custom GLSL, since each filter's unique code lives in the fragment shader.

Source

Thrown at packages/core/src/filters/BaseFilter.ts:117

    if (!vertexShader || !fragmentShader || !program) {
      throw new FabricError(
        'Vertex, fragment shader or program creation error',
      );
    }
    gl.shaderSource(vertexShader, vertexSource);
    gl.compileShader(vertexShader);
    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
      throw new FabricError(
        `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(
          vertexShader,
        )}`,
      );
    }

    gl.shaderSource(fragmentShader, fragmentSource);
    gl.compileShader(fragmentShader);
    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
      throw new FabricError(
        `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(
          fragmentShader,
        )}`,
      );
    }

    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
    gl.linkProgram(program);
    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
      throw new FabricError(
        `Shader link error for "${this.type}" ${gl.getProgramInfoLog(program)}`,
      );
    }

    const uniformLocations = this.getUniformLocations(gl, program) || {};
    uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');
    uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');

View on GitHub (pinned to 2bd4992cab)

Solutions

  1. Read the included info log — it pinpoints the GLSL line and error; fix the fragment source in your custom filter.
  2. Declare `precision highp float;`/`precision mediump float;` and match uniform/varying names exactly with what the filter registers.
  3. Ensure GLSL version compatibility (WebGL1-style texture2D / varying vs WebGL3-style) with the context fabric uses; prefer fabric's own source patterns as a template.
  4. For built-in filters, recreate the context (possible loss/reset) and retry; disable filters if the environment can't compile them.

Example fix

// before
class Tint extends fabric.Image.filters.BaseFilter {
  static type = 'Tint';
  getFragmentSource() { return 'uniform vec4 uColor; void main() { gl_FragColor = uColor }'; } // missing ;
}

// after
class Tint extends fabric.Image.filters.BaseFilter {
  static type = 'Tint';
  getFragmentSource() {
    return `precision highp float;
uniform sampler2D uTexture;
uniform vec4 uColor;
void main() { gl_FragColor = uColor; }`;
  }
}
Defensive patterns

Strategy: fallback

Validate before calling

function fragmentShaderCompiles(src: string): boolean {
  try {
    const gl = document.createElement('canvas').getContext('webgl');
    if (!gl) return false;
    const s = gl.createShader(gl.FRAGMENT_SHADER);
    gl.shaderSource(s, src);
    gl.compileShader(s);
    return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);
  } catch { return false; }
}
if (fragmentShaderCompiles(myFilter.getFragmentSource())) { /* safe to apply */ }

Type guard

const isValidFragmentSource = (src: string): boolean => {
  try {
    const gl = document.createElement('canvas').getContext('webgl');
    if (!gl) return false;
    const s = gl.createShader(gl.FRAGMENT_SHADER)!;
    gl.shaderSource(s, src); gl.compileShader(s);
    return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);
  } catch { return false; }
};

Try / catch

try {
  img.applyFilters();
} catch (e) {
  if (e instanceof Error && e.message.includes('Fragment shader compile error')) {
    console.error(e.message); // contains filter type + GLSL info log
    img.filters = []; // or swap in a known-good filter
  } else throw e;
}

Prevention

When it happens

Trigger: Applying a filter whose fragment source is invalid: custom subclasses overriding getFragmentSource (or GLSL maps) with syntax errors, unsupported extensions, missing precision qualifiers, or wrong varying/uniform declarations; also broken drivers/context loss for built-in filters.

Common situations: Writing a custom fabric.Image.filters.BaseFilter subclass with GLSL mistakes (missing semicolons, undeclared uniforms, texture2D vs texture in WebGL2); copy-pasting WebGL1 GLSL into a WebGL2-only context; driver bugs on older mobile GPUs.

Related errors


AI-assisted analysis of fabricjs/fabric.js@2bd4992cab (2026-08-28). Data as JSON: /api/errors/0c472bf010facad7. Report an issue: GitHub.