{"record":{"id":"27b8c06692864aa2","repo":"fabricjs/fabric.js","slug":"vertex-shader-compile-error-for-this-type-gl","errorCode":null,"errorMessage":"Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n          vertexShader,\n        )}","messagePattern":"Vertex shader compile error for (.+?): (.+?)","errorType":"exception","errorClass":"FabricError","httpStatus":null,"severity":"error","filePath":"packages/core/src/filters/BaseFilter.ts","lineNumber":107,"sourceCode":"    if (GLPrecision !== 'highp') {\n      fragmentSource = fragmentSource.replace(\n        regex,\n        highPsourceCode.replace('highp', GLPrecision),\n      );\n    }\n    const vertexShader = gl.createShader(gl.VERTEX_SHADER);\n    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n    const program = gl.createProgram();\n\n    if (!vertexShader || !fragmentShader || !program) {\n      throw new FabricError(\n        'Vertex, fragment shader or program creation error',\n      );\n    }\n    gl.shaderSource(vertexShader, vertexSource);\n    gl.compileShader(vertexShader);\n    if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {\n      throw new FabricError(\n        `Vertex shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n          vertexShader,\n        )}`,\n      );\n    }\n\n    gl.shaderSource(fragmentShader, fragmentSource);\n    gl.compileShader(fragmentShader);\n    if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {\n      throw new FabricError(\n        `Fragment shader compile error for ${this.type}: ${gl.getShaderInfoLog(\n          fragmentShader,\n        )}`,\n      );\n    }\n\n    gl.attachShader(program, vertexShader);\n    gl.attachShader(program, fragmentShader);","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/fabricjs/fabric.js/blob/2bd4992cabf4ec9609aa349ea09b723cadc94bef/packages/core/src/filters/BaseFilter.ts#L89-L125","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["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.","If using built-in filters, treat it as environment failure: recreate the canvas/context and retry, and listen for webglcontextlost.","Check the info log included in the message — it names the exact line and error in the shader source.","Fall back to disabling filters (or CPU-based processing) when WebGL compilation fails."],"exampleFix":"// before\nclass MyFilter extends fabric.Image.filters.BaseFilter {\n  static type = 'MyFilter';\n  getFragmentSource() { return 'void main( { broken glsl'; } // compile error\n}\n\n// after\nclass MyFilter extends fabric.Image.filters.BaseFilter {\n  static type = 'MyFilter';\n  getFragmentSource() {\n    return `precision highp float;\nvoid main() { gl_FragColor = vec4(1.0); }`;\n  }\n}","handlingStrategy":"fallback","validationCode":"// Compile-test shader support once per page before enabling filters\nfunction filtersCompileOK(): boolean {\n  try {\n    const gl = document.createElement('canvas').getContext('webgl');\n    if (!gl) return false;\n    const s = gl.createShader(gl.VERTEX_SHADER);\n    gl.shaderSource(s, 'void main() { gl_Position = vec4(0.0); }');\n    gl.compileShader(s);\n    return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);\n  } catch { return false; }\n}","typeGuard":"const vertexShaderCompiles = (gl: WebGLRenderingContext): boolean => {\n  const s = gl.createShader(gl.VERTEX_SHADER);\n  if (!s) return false;\n  gl.shaderSource(s, 'void main() { gl_Position = vec4(0.0); }');\n  gl.compileShader(s);\n  return !!gl.getShaderParameter(s, gl.COMPILE_STATUS);\n};","tryCatchPattern":"try {\n  img.applyFilters();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Vertex shader compile error')) {\n    console.error(e.message); // log includes GLSL info log with failing line\n    img.filters = []; // fallback: render unfiltered\n  } else throw e;\n}","preventionTips":["For custom filters, run GLSL through a validator or standalone WebGL page first.","Reuse Fabric's built-in vertex/fragment source helpers rather than hand-writing boilerplate.","Log and surface the info log text — it identifies the exact shader line at fault.","Provide a no-filter fallback so one bad GPU/driver doesn't break rendering."],"tags":["fabricjs","webgl","glsl","shader-compile","custom-filter"],"backgroundTag":"shader-compilation-failed","analyzedSha":"2bd4992cabf4ec9609aa349ea09b723cadc94bef","analyzedAt":"2026-08-28T10:56:44.286Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}