{"record":{"id":"d54f71b03d2217d9","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-shader-d54f71","errorCode":null,"errorMessage":"Failed to create WebGL shader","messagePattern":"Failed to create WebGL shader","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/zigzag.ts","lineNumber":349,"sourceCode":"\t\t);\n\t\treturn;\n\t}\n\n\tfragColor = vec4(\n\t\tpremultipliedLine + texColor.rgb * (1.0 - lineAlpha),\n\t\tlineAlpha + texColor.a * (1.0 - lineAlpha)\n\t);\n}\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(`Zigzag shader compile failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn shader;\n};\n\nconst linkProgram = (\n\tgl: WebGL2RenderingContext,\n\tvs: WebGLShader,\n\tfs: WebGLShader,\n): WebGLProgram => {","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/zigzag.ts#L331-L367","documentation":"Zigzag's shader pipeline starts by allocating a shader object via gl.createShader; if the GL context returns null the effect cannot compile its (constant) vertex/fragment sources and throws. As with all null-resource throws here, this is a context/resource failure — the GLSL itself is fixed and valid, so the cause is a lost context, shader-object limit, or software renderer.","triggerScenarios":"setupZigzag -> createProgram -> compileShader calls gl.createShader(type) and receives null on the first zigzag frame.","commonSituations":"Headless render without working WebGL2/GPU; many concurrent effects exhausting shader-object slots; context lost before compile; VM/Remote-Desktop GPU forwarding missing shader allocation.","solutions":["Confirm WebGL2 is available and the context is not lost before applying zigzag().","Render with Remotion's bundled Chromium (CLI/Lambda) which configures the software GPU correctly; avoid --disable-gpu.","Reduce concurrently-active WebGL effects to free GL object slots.","Re-mount the composition on webglcontextlost so setup re-runs.","Update GPU drivers or switch render host."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const gl = document.createElement('canvas').getContext('webgl2');\nconst webglOk = gl != null && gl.createShader(gl.VERTEX_SHADER) != null && !gl.isContextLost();","typeGuard":"const canAllocateShader = (): boolean => {\n  const gl = document.createElement('canvas').getContext('webgl2');\n  return gl != null && !gl.isContextLost() && gl.createShader(gl.VERTEX_SHADER) != null;\n};","tryCatchPattern":"try {\n  return <VideoEffects effects={[zigzag({colors: ['#ff0000', '#00ff00']})]} />;\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL shader') {\n    return <Video />; // GPU shader allocation failed; skip the effect\n  }\n  throw err;\n}","preventionTips":["Probe shader-object allocation before mounting zigzag().","Render with Remotion's bundled Chromium; avoid disabling the GPU.","Cap concurrent WebGL effects to free shader slots.","Re-create the context on webglcontextlost."],"tags":["webgl","gpu","shader","rendering","headless"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}