{"record":{"id":"85734cedf6edffb3","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-shader-85734c","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/rings.ts","lineNumber":278,"sourceCode":"\t\t);\n\t\treturn;\n\t}\n\n\tfragColor = vec4(\n\t\tpremultipliedRing + texColor.rgb * (1.0 - ringAlpha),\n\t\tringAlpha + texColor.a * (1.0 - ringAlpha)\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(`Rings 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":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/rings.ts#L260-L296","documentation":"Internal error from the `rings()` effect's WebGL2 setup: `gl.createShader()` returned `null`. The WebGL2 context was acquired successfully, but the driver refused to allocate a new shader object. This is an environment-level failure (context loss, GPU memory exhaustion, or a driver that has already created too many shaders), not a user-param error. The shaders themselves are compile-time string constants, so a param change cannot cause it.","triggerScenarios":"Calling `rings()` in a browser tab whose WebGL2 context was lost (e.g. after the GPU process crashed or the system resumed from sleep); running many effect instances concurrently until the driver's shader object limit is hit; rendering in a headless Chromium with a software GL implementation that has unstable shader allocation.","commonSituations":"Long-running Remotion Studio sessions that leak WebGL contexts; CI render farms using SwiftShader/llvmpipe under memory pressure; switching GPU on a dual-GPU laptop mid-render; too many simultaneously-mounted effect components.","solutions":["Reload the page / restart the render to get a fresh WebGL2 context.","Reduce the number of effects mounted at once to free GPU resources.","Update or switch GPU drivers; if using software GL in CI, allocate more memory or use a hardware-accelerated runner.","If it reproduces deterministically, file a Remotion issue with the GPU/driver info from `WEBGL_debug_renderer_info`."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"const supportsWebGL2 = (): boolean => {\n  try {\n    const c = document.createElement('canvas');\n    return !!c.getContext('webgl2');\n  } catch {\n    return false;\n  }\n};\n\nif (!supportsWebGL2()) {\n  // fall back to a non-effect composition\n}","typeGuard":null,"tryCatchPattern":"try {\n  rings()({...});\n} catch (err) {\n  if (err instanceof Error && /Failed to create WebGL shader/.test(err.message)) {\n    // surface a friendly 'GPU context unavailable' message and retry once after reload\n  } else {\n    throw err;\n  }\n}","preventionTips":["Feature-detect WebGL2 before mounting effects.","Limit the number of simultaneously active effects to avoid exhausting shader objects.","Handle `webglcontextlost` on the canvas and re-create the effect on restore.","Prefer hardware-accelerated environments for CI rendering."],"tags":["webgl2","rings-effect","effects","gpu","environment","resource-allocation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}