{"record":{"id":"3b2348128a2a7cec","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-texture-3b2348","errorCode":null,"errorMessage":"Failed to create WebGL texture","messagePattern":"Failed to create WebGL texture","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/evolve.ts","lineNumber":237,"sourceCode":"\t\tthrow new Error('Failed to create WebGL program');\n\t}\n\n\tgl.attachShader(program, vs);\n\tgl.attachShader(program, fs);\n\tgl.linkProgram(program);\n\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\tconst log = gl.getProgramInfoLog(program);\n\t\tgl.deleteProgram(program);\n\t\tthrow new Error(`Evolve program link failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn program;\n};\n\nconst createRgbaTexture = (gl: WebGL2RenderingContext): WebGLTexture => {\n\tconst texture = gl.createTexture();\n\tif (!texture) {\n\t\tthrow new Error('Failed to create WebGL texture');\n\t}\n\n\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\treturn texture;\n};\n\nconst setupEvolve = (target: HTMLCanvasElement): EvolveState => {\n\tconst gl = target.getContext('webgl2', {\n\t\tpremultipliedAlpha: true,\n\t\talpha: true,\n\t\tpreserveDrawingBuffer: true,\n\t});\n","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/evolve.ts#L219-L255","documentation":"Thrown inside createRgbaTexture() in evolve.ts when gl.createTexture() returns null during setupEvolve(). A null return means the GL implementation could not allocate another texture object — typically because the context is lost or GPU texture memory/object pools are exhausted. No texture can be created, so evolve setup aborts.","triggerScenarios":"evolve() effect setup runs after a webglcontextlost event (the spec forces createTexture to return null while lost), or when the page has exhausted the driver's texture-object limit by leaking textures across many effect canvases. The check is the bare `if (!texture)` at evolve.ts:236.","commonSituations":"Long-running Studio sessions where old effect canvases were not cleaned up (cleanup() not called); rendering many simultaneous evolve layers in one composition; headless render hosts with limited GPU memory; a prior crash of the GPU process leaving contexts in a lost state.","solutions":["Ensure effects are torn down: rely on Remotion's effect lifecycle so cleanup() runs (it calls gl.deleteTexture); avoid holding references to old effect states.","Render with --gl=angle (CLI) / chromiumOptions: { gl: 'angle' } (SSR) / Angle backend (Studio) for more reliable texture allocation under SwiftShader.","Reduce the count of concurrent evolve() instances in the composition and reuse identical param combinations so calculateKey collapses them onto one canvas.","Handle webglcontextlost on the canvas and trigger a context-restoration flow before retrying the render.","Move rendering to a host with more GPU memory, or run a software GL fallback consistently."],"exampleFix":"// before\nconst texture = gl.createTexture();\nif (!texture) {\n  throw new Error('Failed to create WebGL texture');\n}\n\n// after (caller-side health check before evolve setup)\nif (gl.isContextLost()) {\n  // wait for webglcontextrestored before re-applying evolve()\n  return;\n}","handlingStrategy":"try-catch","validationCode":"// Health check before driving evolve on a canvas you control.\nconst canAllocateTexture = (gl: WebGL2RenderingContext): boolean => {\n  if (gl.isContextLost()) return false;\n  const probe = gl.createTexture();\n  if (!probe) return false;\n  gl.deleteTexture(probe);\n  return true;\n};","typeGuard":null,"tryCatchPattern":"try {\n  // declarative usage; for a custom canvas:\n  // const state = setupEvolve(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL texture') {\n    // likely context loss or exhaustion: free other effects, restore context, retry\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Render with the Angle backend (--gl=angle / chromiumOptions.gl='angle').","Let Remotion's effect lifecycle manage cleanup() so textures are deleted, not leaked.","Avoid stacking many evolve() instances in one composition; reuse identical params.","Monitor webglcontextlost on long-running Studio sessions and restore the context."],"tags":["webgl","texture","resource-allocation","gpu","evolve","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}