fabricjs/fabric.js · error · FabricError

Vertex shader compile error for ${this.type}: ${gl.getShader

Error message

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

What it means

Fabric's BaseFilter.createProgram compiles a vertex shader for each filter type; if gl.compileShader reports a falsy COMPILE_STATUS, this error is thrown with the driver's info log. The vertex shader comes from Fabric's own GLSL boilerplate (main vertex code is shared across filters), so a compile failure usually means a broken/lost WebGL context, an incomplete GLSL implementation in the driver, or corrupted/custom shader source rather than user configuration.

Source

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

    if (GLPrecision !== 'highp') {
      fragmentSource = fragmentSource.replace(
        regex,
        highPsourceCode.replace('highp', GLPrecision),
      );
    }
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
    const program = gl.createProgram();

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

View on GitHub (pinned to 2bd4992cab)

Solutions

  1. If you wrote a custom filter, validate your GLSL (getVertexSource override) with a standalone WebGL test or reference compiler; fix syntax/precision/qualifier errors reported in the message.
  2. If using built-in filters, treat it as environment failure: recreate the canvas/context and retry, and listen for webglcontextlost.
  3. Check the info log included in the message — it names the exact line and error in the shader source.
  4. Fall back to disabling filters (or CPU-based processing) when WebGL compilation fails.

Example fix

// before
class MyFilter extends fabric.Image.filters.BaseFilter {
  static type = 'MyFilter';
  getFragmentSource() { return 'void main( { broken glsl'; } // compile error
}

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

Strategy: fallback

Validate before calling

// Compile-test shader support once per page before enabling filters
function filtersCompileOK(): boolean {
  try {
    const gl = document.createElement('canvas').getContext('webgl');
    if (!gl) return false;
    const s = gl.createShader(gl.VERTEX_SHADER);
    gl.shaderSource(s, 'void main() { gl_Position = vec4(0.0); }');
    gl.compileShader(s);
    return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);
  } catch { return false; }
}

Type guard

const vertexShaderCompiles = (gl: WebGLRenderingContext): boolean => {
  const s = gl.createShader(gl.VERTEX_SHADER);
  if (!s) return false;
  gl.shaderSource(s, 'void main() { gl_Position = vec4(0.0); }');
  gl.compileShader(s);
  return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);
};

Try / catch

try {
  img.applyFilters();
} catch (e) {
  if (e instanceof Error && e.message.includes('Vertex shader compile error')) {
    console.error(e.message); // log includes GLSL info log with failing line
    img.filters = []; // fallback: render unfiltered
  } else throw e;
}

Prevention

When it happens

Trigger: Applying any fabric.Image.filters.* filter when the WebGL context is in a bad state (lost/reset), on drivers with partial GLSL ES support, or when a custom filter subclass supplies invalid GLSL in getVertexSource/getFragmentSource overrides.

Common situations: Custom filter subclasses overriding shader source with syntax errors or unsupported GLSL features; mobile/embedded GPUs or virtualized/headless GL (SwiftShader) with quirks; context loss mid-session; browser/driver version changes after an update.

Related errors


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