{"record":{"id":"d219c511a6246f4c","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-shader-d219c5","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/light-trail/light-trail-runtime.ts","lineNumber":36,"sourceCode":"\t\treadonly uDistance: WebGLUniformLocation | null;\n\t\treadonly uIntensity: WebGLUniformLocation | null;\n\t\treadonly uDecay: WebGLUniformLocation | null;\n\t\treadonly uThreshold: WebGLUniformLocation | null;\n\t\treadonly uSamples: WebGLUniformLocation | null;\n\t};\n\treadonly colorCtx: 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(`Light trail 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":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/light-trail/light-trail-runtime.ts#L18-L54","documentation":"Thrown from lightTrail's WebGL2 setup when `gl.createShader(type)` returns `null`. Per the WebGL spec a non-null return only fails under context loss, GL_OUT_OF_MEMORY, or an implementation that has run out of object handles — the shader source has not even been set yet at this point.","triggerScenarios":"Setting up many lightTrail (or other WebGL) effects concurrently until the GL driver runs out of shader handles; a context-loss event firing mid-setup; rendering in a headless/Chromium-for-Testing build with software rendering that refuses object creation; running after a previous GL error left the context in a lost state.","commonSituations":"Rendering long videos with dozens of stacked effects on one frame; CI/headless Chrome with `--disable-gpu` but WebGL2 still nominally supported; older Linux Mesa drivers; remotion-lambda Chrome hitting a transient GL reset; reopening Studio many times in a session that leaks contexts.","solutions":["Register a `webglcontextlost` listener on the canvas and surface a user-facing error or reload the composition rather than retrying blindly.","Reduce the number of simultaneously active WebGL effects in the frame; share or cache effect state across frames (the effect already keys by params in its setup cache).","In headless rendering, ensure the Chrome build has GPU available (Lambda uses a real GPU layer) and avoid `--disable-gpu`.","If context loss is the cause, dispose and recreate the effect's setup once the `webglcontextrestored` event fires.","Update GPU drivers / Mesa on self-hosted render workers."],"exampleFix":"// before\nconst state = setupLightTrail(canvas);\n\n// after\ncanvas.addEventListener('webglcontextlost', (e) => {\n  e.preventDefault();\n  cleanupLightTrail(prevState);\n  reportRenderError('lightTrail unavailable: WebGL context lost');\n}, { once: true });\ntry {\n  const state = setupLightTrail(canvas);\n} catch (err) {\n  // fall back to a non-WebGL composition branch\n}","handlingStrategy":"fallback","validationCode":"const webgl2Available = (canvas: HTMLCanvasElement): boolean => {\n  try {\n    return !!canvas.getContext('webgl2');\n  } catch {\n    return false;\n  }\n};","typeGuard":"const supportsWebGL2 = (): boolean => {\n  try {\n    const c = document.createElement('canvas');\n    return !!c.getContext('webgl2');\n  } catch {\n    return false;\n  }\n};","tryCatchPattern":"let state;\ntry {\n  state = setupLightTrail(canvas);\n} catch (err) {\n  // WebGL2 can't allocate right now — render without the effect.\n  console.error('lightTrail unavailable, falling back', err);\n  state = null;\n}","preventionTips":["Register webglcontextlost listeners and never retry setup while lost.","Cache and reuse effect state instead of allocating per frame.","Render on GPU-enabled workers; avoid --disable-gpu in headless Chrome."],"tags":["webgl","light-trail","effects","gpu","resource-exhaustion"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}