{"record":{"id":"75a25fb77163f269","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-shader-75a25f","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/pixelate.ts","lineNumber":87,"sourceCode":"uniform sampler2D uSource;\nuniform float uBlockSize;\nuniform vec2 uResolution;\n\nvoid main() {\n    vec2 pixelSizeUv = vec2(uBlockSize) / uResolution;\n    vec2 blockUv = floor(vUv / pixelSizeUv) * pixelSizeUv + pixelSizeUv * 0.5;\n    fragColor = texture(uSource, blockUv);\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(`Pixelate 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":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/pixelate.ts#L69-L105","documentation":"Thrown by compileShader in pixelate.ts when gl.createShader() returns null. The shader object is the first thing needed to compile GLSL, and a null return means the GL implementation cannot allocate another shader — almost always because the context is lost or has hit an internal shader-object cap. The guard prevents shaderSource/compileShader from receiving null.","triggerScenarios":"pixelate() setup calls compileShader for the vertex shader (or fragment shader); gl.createShader(type) returns null. No GLSL has been compiled yet at this point, so the failure is purely about GL object allocation, not source correctness.","commonSituations":"Headless Chrome without GPU (SwiftShader); context lost between frames; many WebGL2 effects each allocating their own shaders in one tab; driver that caps total shader objects; environment that returned a WebGL2 context object but cannot actually service it (some virtualized GPU setups).","solutions":["Confirm WebGL2 is functional with a probe: `const gl=canvas.getContext('webgl2'); const s=gl && gl.createShader(gl.VERTEX_SHADER);` — if s is null, the environment is the cause.","On Remotion Lambda use the published Chrome layer with SwiftShader enabled; do not run with --disable-gpu without --use-gl=swiftshader.","Reduce the number of distinct WebGL2 effects mounted concurrently; each pixelate instance compiles two shaders.","Listen for 'webglcontextlost' on the canvas and remount the effect when 'webglcontextrestored' fires.","Update the GPU driver if reproducing on a single physical machine."],"exampleFix":"// before\nimport {pixelate} from '@remotion/effects';\nconst effect = pixelate();\n\n// after — detect before mounting\nfunction webgl2CanCompileShader(): boolean {\n  const c = document.createElement('canvas');\n  const gl = c.getContext('webgl2');\n  if (!gl) return false;\n  const s = gl.createShader(gl.VERTEX_SHADER);\n  if (s) gl.deleteShader(s);\n  return s !== null;\n}","handlingStrategy":"try-catch","validationCode":"function glCanCreateShader(gl: WebGL2RenderingContext): boolean {\n  if (gl.isContextLost()) return false;\n  const s = gl.createShader(gl.VERTEX_SHADER);\n  if (s) gl.deleteShader(s);\n  return s !== null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  pixelate();\n} catch (err) {\n  if (/Failed to create WebGL shader/.test((err as Error).message)) {\n    // report WebGL2 unavailable; fall back to a non-GPU effect\n  }\n  throw err;\n}","preventionTips":["Feature-detect shader allocation in headless/CI environments before rendering.","On Lambda use the bundled Chrome for Testing layer.","Handle context-loss events and remount effects on restore.","Limit concurrent WebGL2 effects to keep shader-object count under driver caps."],"tags":["webgl","gpu","pixelate","shader","environment","headless"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}