{"record":{"id":"1f3f6f5e8e48e9c8","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-vertex-array-1f3f6f","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/fisheye/fisheye-runtime.ts","lineNumber":110,"sourceCode":"};\n\nexport const setupFisheye = (target: HTMLCanvasElement): FisheyeState => {\n\tconst gl = target.getContext('webgl2', {\n\t\tpremultipliedAlpha: true,\n\t\talpha: true,\n\t\tpreserveDrawingBuffer: true,\n\t});\n\tif (!gl) {\n\t\tthrow createWebGL2ContextError('fisheye effect');\n\t}\n\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n\n\tconst program = createProgram(gl, FISHEYE_VS, FISHEYE_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\tgl.enableVertexAttribArray(0);\n\tgl.vertexAttribPointer(0, 2, gl.FLOAT, false, 16, 0);","sourceCodeStart":92,"sourceCodeEnd":128,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/fisheye/fisheye-runtime.ts#L92-L128","documentation":"Thrown during setupFisheye() when gl.createVertexArray() returns null (fisheye-runtime.ts:108-111). A null VAO means the driver refused another vertex-array object — context lost or the driver's VAO ceiling reached. Without a VAO the fisheye fullscreen-quad attribute state cannot be captured, so setup fails.","triggerScenarios":"setupFisheye() runs createProgram() successfully, then gl.createVertexArray() returns null. This happens on a lost context or when the driver's implementation-defined VAO limit is exhausted by many simultaneous WebGL2 effects or leaked VAOs from un-cleaned fisheye states.","commonSituations":"Compositions stacking numerous WebGL2 effects (each holds a VAO) on a driver with a low VAO cap; apps using fisheye-runtime without cleanupFisheye() (which would gl.deleteVertexArray); GPU process crash leaving the context lost; CI software-GL backends with tight VAO limits.","solutions":["Render with the Angle backend (--gl=angle / chromiumOptions.gl='angle') for higher, consistent VAO limits.","Reduce concurrent WebGL2 effects and reuse identical fisheye() params (calculateKey caching).","If using the runtime directly, always call cleanupFisheye() so VAOs are recycled.","Verify gl.isContextLost() is false and restore the context if needed.","Update GPU drivers; older drivers leak VAOs across resets."],"exampleFix":"// before\nconst vao = gl.createVertexArray();\nif (!vao) {\n  throw new Error('Failed to create WebGL vertex array');\n}\n\n// after (cleanup discipline)\nconst state = setupFisheye(canvas);\ntry { /* applyFisheye(...) */ } finally { cleanupFisheye(state); }","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":"import {setupFisheye, cleanupFisheye} from '@remotion/effects/fisheye-runtime';\n\nlet state;\ntry {\n  state = setupFisheye(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL vertex array') {\n    // reduce concurrent WebGL2 effects, retry on Angle\n    throw err;\n  }\n  throw err;\n}\ntry { /* applyFisheye(state, ...) */ } finally { cleanupFisheye(state); }","preventionTips":["When using fisheye-runtime directly, always call cleanupFisheye() so VAOs are recycled.","Render with Angle for higher VAO limits.","Reduce simultaneous WebGL2 effects; reuse identical fisheye() params via calculateKey.","Keep GPU drivers current; older drivers leak VAOs across resets."],"tags":["webgl","vertex-array","vao","resource-allocation","gpu","fisheye","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}