fabricjs/fabric.js · error · FabricError

Shader link error for "${this.type}" ${gl.getProgramInfoLog(

Error message

Shader link error for "${this.type}" ${gl.getProgramInfoLog(program)}

What it means

Thrown when a WebGL program fails to link its vertex and fragment shaders. Fabric.js compiles shader source per filter type and links them into a gl program; if gl.linkProgram reports LINK_STATUS false, the info log is included in the message. It usually means one shader failed semantics that only appear at link time, or the GL context is broken/lost.

Source

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

        )}`,
      );
    }

    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');

    return {
      program,
      attributeLocations: this.getAttributeLocations(gl, program),
      uniformLocations,
    };
  }

  /**
   * Return a map of attribute names to WebGLAttributeLocation objects.
   *

View on GitHub (pinned to 2bd4992cab)

Solutions

  1. Check gl.getProgramInfoLog output in the message to identify the GLSL link problem (missing varyings, unresolved functions, version mismatch)
  2. If using a custom filter, verify your fragmentShader/vertexShader compile and that varyings/uniforms match between stages
  3. Verify the WebGL context is not lost (canvas.getContext('webgl') returns a valid context); re-create the canvas or call cleanupCaches if needed
  4. Upgrade fabric to the latest version in case the filter shader is incompatible with your browser/GPU
  5. Fallback to a CPU filter (e.g. 2d canvas based resize/filter) or disable WebGL filters on affected devices

Example fix

// before
const filter = new fabric.filters.Blur({ blur: 0.5 });
image.filters = [filter];
image.applyFilters(); // may throw shader link error on broken GL context

// after
try {
  image.applyFilters();
} catch (e) {
  console.warn('WebGL filter failed, falling back', e);
  image.filters = []; // or use a non-WebGL fallback
  image.applyFilters();
}
Defensive patterns

Strategy: try-catch

Validate before calling

const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');
if (!gl) {
  // skip WebGL filters, use fallback rendering
}

Type guard

const isWebGLAvailable = (canvas: HTMLCanvasElement): boolean =>
  !!(canvas.getContext('webgl2') || canvas.getContext('webgl'));

Try / catch

try {
  image.applyFilters();
} catch (e) {
  if (e instanceof Error && e.message.includes('Shader link error')) {
    // degrade: remove WebGL filters or re-init canvas
  } else throw e;
}

Prevention

When it happens

Trigger: Using a WebGL-backed filter (e.g. Blur, Convolute) whose shader source is incompatible with the browser's GLSL version, or after the WebGL context is lost/recreated in a stale state. Also triggered by custom filters with mismatching vertex/fragment shader varying declarations or unsupported GLSL features.

Common situations: Running an outdated Fabric version on new browser GLSL strictness, a custom filter subclass with bad/mismatched shader code, GPU driver issues, or context loss in long-running SPAs that cache StaticCanvasImpl/GL contexts.

Related errors


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