{"record":{"id":"4ae691fbc3463164","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-shader-4ae691","errorCode":null,"errorMessage":"Failed to create WebGL shader","messagePattern":"Failed to create WebGL shader","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/effects/src/halftone-linear-gradient.ts","lineNumber":376,"sourceCode":"\tuFirstStopPosition: WebGLUniformLocation | null;\n\tuSecondStopPosition: WebGLUniformLocation | null;\n\tuGridSize: WebGLUniformLocation | null;\n\tuColor: WebGLUniformLocation | null;\n\tuUseSourceColor: WebGLUniformLocation | null;\n\tuMaskToSourceAlpha: WebGLUniformLocation | null;\n\tcolorCtx: CanvasRenderingContext2D;\n\tcachedColorStr: string;\n\tcachedColorRgba: ParsedColorRgba;\n};\n\nconst compileShader = (\n\tgl: WebGL2RenderingContext,\n\ttype: number,\n\tsource: string,\n): WebGLShader => {\n\tconst shader = gl.createShader(type);\n\tif (!shader) {\n\t\tthrow new Error('Failed to create WebGL shader');\n\t}\n\n\tgl.shaderSource(shader, source);\n\tgl.compileShader(shader);\n\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\tconst log = gl.getShaderInfoLog(shader);\n\t\tgl.deleteShader(shader);\n\t\tthrow new Error(\n\t\t\t`Halftone linear gradient shader compile failed: ${log ?? '(no log)'}`,\n\t\t);\n\t}\n\n\treturn shader;\n};\n\nconst linkProgram = (\n\tgl: WebGL2RenderingContext,\n\tvs: WebGLShader,","sourceCodeStart":358,"sourceCodeEnd":394,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/halftone-linear-gradient.ts#L358-L394","documentation":"Thrown by halftone-linear-gradient's compileShader (halftone-linear-gradient.ts:376) when gl.createShader(type) returns null. A null shader object indicates a lost WebGL2 context or GPU resource exhaustion. The library throws because subsequent gl.shaderSource would crash on null.","triggerScenarios":"Called during the halftone effect setup (lines 442-447) for both the vertex and fragment shaders, right after acquiring the webgl2 context. Fires on context loss, on leaked shader objects, or when the driver's shader budget is exhausted.","commonSituations":"Long render leaking GL objects; many concurrent WebGL effects/compositions; GPU reset mid-render; constrained integrated GPUs or software renderers.","solutions":["Register a webglcontextlost handler and rebuild effect state on webglcontextrestored.","Always call cleanup() to free shaders/programs/buffers/textures.","Reduce the number of live WebGL2 effects; render sequentially on constrained GPUs.","Restart browser/GPU; update drivers if the failure is reproducible."],"exampleFix":"// before: repeated setup without teardown -> eventual null allocation\nuseEffect(() => { halftone.setup(canvas); }, [frame]);\n\n// after: setup once, cleanup on unmount, handle context loss\nuseEffect(() => {\n  const canvas = ref.current!;\n  const onLost = (e: Event) => e.preventDefault();\n  canvas.addEventListener('webglcontextlost', onLost);\n  const s = halftone.setup(canvas);\n  return () => { halftone.cleanup(s); canvas.removeEventListener('webglcontextlost', onLost); };\n}, []);","handlingStrategy":"try-catch","validationCode":"const gl = canvas.getContext('webgl2');\nif (!gl) throw new Error('WebGL2 unavailable');\nif (gl.isContextLost()) throw new Error('WebGL2 context lost before shader allocation');","typeGuard":"null","tryCatchPattern":"try {\n  halftoneLinearGradient.setup(canvas);\n} catch (e) {\n  if (e instanceof Error && e.message === 'Failed to create WebGL shader') {\n    // context loss / resource exhaustion: recreate, reduce load\n  }\n  throw e;\n}","preventionTips":["Handle webglcontextlost/webglcontextrestored on the canvas.","Always pair setup() with cleanup() to free shaders.","Avoid creating WebGL contexts in a render loop.","Limit concurrent WebGL compositions on constrained GPUs."],"tags":["webgl","halftone-linear-gradient-effect","shader","gpu","resource-exhaustion"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}