{"record":{"id":"a24eabd4caed0b03","repo":"fabricjs/fabric.js","slug":"shader-link-error-for-this-type-gl-getprogr","errorCode":null,"errorMessage":"Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}","messagePattern":"Shader link error for \"(.+?)\" (.+?)","errorType":"exception","errorClass":"FabricError","httpStatus":null,"severity":"error","filePath":"packages/core/src/filters/BaseFilter.ts","lineNumber":128,"sourceCode":"        )}`,\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);\n    gl.linkProgram(program);\n    if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n      throw new FabricError(\n        `Shader link error for \"${this.type}\" ${gl.getProgramInfoLog(program)}`,\n      );\n    }\n\n    const uniformLocations = this.getUniformLocations(gl, program) || {};\n    uniformLocations.uStepW = gl.getUniformLocation(program, 'uStepW');\n    uniformLocations.uStepH = gl.getUniformLocation(program, 'uStepH');\n\n    return {\n      program,\n      attributeLocations: this.getAttributeLocations(gl, program),\n      uniformLocations,\n    };\n  }\n\n  /**\n   * Return a map of attribute names to WebGLAttributeLocation objects.\n   *","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/fabricjs/fabric.js/blob/2bd4992cabf4ec9609aa349ea09b723cadc94bef/packages/core/src/filters/BaseFilter.ts#L110-L146","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check gl.getProgramInfoLog output in the message to identify the GLSL link problem (missing varyings, unresolved functions, version mismatch)","If using a custom filter, verify your fragmentShader/vertexShader compile and that varyings/uniforms match between stages","Verify the WebGL context is not lost (canvas.getContext('webgl') returns a valid context); re-create the canvas or call cleanupCaches if needed","Upgrade fabric to the latest version in case the filter shader is incompatible with your browser/GPU","Fallback to a CPU filter (e.g. 2d canvas based resize/filter) or disable WebGL filters on affected devices"],"exampleFix":"// before\nconst filter = new fabric.filters.Blur({ blur: 0.5 });\nimage.filters = [filter];\nimage.applyFilters(); // may throw shader link error on broken GL context\n\n// after\ntry {\n  image.applyFilters();\n} catch (e) {\n  console.warn('WebGL filter failed, falling back', e);\n  image.filters = []; // or use a non-WebGL fallback\n  image.applyFilters();\n}","handlingStrategy":"try-catch","validationCode":"const gl = canvas.getContext('webgl2') || canvas.getContext('webgl');\nif (!gl) {\n  // skip WebGL filters, use fallback rendering\n}","typeGuard":"const isWebGLAvailable = (canvas: HTMLCanvasElement): boolean =>\n  !!(canvas.getContext('webgl2') || canvas.getContext('webgl'));","tryCatchPattern":"try {\n  image.applyFilters();\n} catch (e) {\n  if (e instanceof Error && e.message.includes('Shader link error')) {\n    // degrade: remove WebGL filters or re-init canvas\n  } else throw e;\n}","preventionTips":["Feature-detect WebGL before enabling WebGL filters","Avoid caching filtered canvases across context-loss events; listen for webglcontextlost and rebuild","Keep fabric updated so filter shaders match current GLSL strictness","Test custom filter shaders in the browsers/GPUs you support"],"tags":["webgl","shader","gpu","filter","glsl"],"backgroundTag":"webgl-shader-compile-error","analyzedSha":"2bd4992cabf4ec9609aa349ea09b723cadc94bef","analyzedAt":"2026-08-28T10:56:44.286Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}