{"record":{"id":"103840f7febc4beb","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-vertex-array-103840","errorCode":null,"errorMessage":"Failed to create WebGL vertex array","messagePattern":"Failed to create WebGL vertex array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/evolve.ts","lineNumber":270,"sourceCode":"\t\talpha: true,\n\t\tpreserveDrawingBuffer: true,\n\t});\n\n\tif (!gl) {\n\t\tthrow createWebGL2ContextError('evolve effect');\n\t}\n\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n\n\tconst vs = compileShader(gl, gl.VERTEX_SHADER, EVOLVE_VS);\n\tconst fs = compileShader(gl, gl.FRAGMENT_SHADER, EVOLVE_FS);\n\tconst program = linkProgram(gl, vs, fs);\n\tgl.deleteShader(vs);\n\tgl.deleteShader(fs);\n\n\tconst vao = gl.createVertexArray();\n\tif (!vao) {\n\t\tthrow new Error('Failed to create WebGL vertex array');\n\t}\n\n\tgl.bindVertexArray(vao);\n\n\tconst data = new Float32Array([\n\t\t-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1,\n\t]);\n\n\tconst vbo = gl.createBuffer();\n\tif (!vbo) {\n\t\tthrow new Error('Failed to create WebGL buffer');\n\t}\n\n\tgl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n\tgl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);\n\n\tconst aPos = gl.getAttribLocation(program, 'aPos');\n\tconst aUv = gl.getAttribLocation(program, 'aUv');","sourceCodeStart":252,"sourceCodeEnd":288,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/evolve.ts#L252-L288","documentation":"Thrown during setupEvolve() when gl.createVertexArray() returns null (evolve.ts:269-271). A null VAO means the driver refused to allocate another vertex-array object — almost always a lost context or an exhausted VAO pool. Without a VAO the evolve geometry cannot be captured, so setup stops.","triggerScenarios":"evolve() setup runs against a lost WebGL2 context, or the driver has hit its implementation-defined VAO limit (some drivers cap VAOs far below textures/buffers). The guard is the `if (!vao)` check immediately after the program is linked.","commonSituations":"A composition stacking many WebGL2 effects (each consumes a VAO) on a driver with a low VAO ceiling; a GPU process crash mid-render leaving the context lost; software GL backends with tight object limits in CI.","solutions":["Render with the Angle backend (--gl=angle / chromiumOptions.gl='angle') which has higher, more consistent VAO limits.","Cut the number of simultaneous WebGL2 effects in the composition, or share one evolve() instance across layers via identical params so calculateKey reuses state.","Verify the context is healthy with gl.isContextLost() and restore before retrying.","Update GPU drivers; some older drivers leak VAOs across context resets.","On CI, pin a software GL path that is known to handle your effect count."],"exampleFix":"// before\nconst vao = gl.createVertexArray();\nif (!vao) {\n  throw new Error('Failed to create WebGL vertex array');\n}\n\n// after (composition-level: collapse duplicate effects onto one canvas)\n// evolve({progress: 0.5, direction: 'left', feather: 0.1}) // repeated per layer\n// -> compute the param set once and reuse the same evolve() reference.","handlingStrategy":"try-catch","validationCode":"const canAllocateVao = (gl: WebGL2RenderingContext): boolean => {\n  if (gl.isContextLost()) return false;\n  const probe = gl.createVertexArray();\n  if (!probe) return false;\n  gl.deleteVertexArray(probe);\n  return true;\n};","typeGuard":null,"tryCatchPattern":"try {\n  // apply evolve(); for a custom canvas: const state = setupEvolve(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL vertex array') {\n    // reduce concurrent WebGL2 effects, then retry on Angle\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Render with Angle for higher VAO limits.","Reduce simultaneous WebGL2 effects; reuse identical evolve() params via calculateKey.","Ensure cleanup() runs (gl.deleteVertexArray) so VAOs are recycled.","Keep GPU drivers current; older drivers leak VAOs across resets."],"tags":["webgl","vertex-array","vao","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"}