{"record":{"id":"c4fd267638d98bb7","repo":"remotion-dev/remotion","slug":"failed-to-create-exposure-vertex-array","errorCode":null,"errorMessage":"Failed to create exposure vertex array","messagePattern":"Failed to create exposure vertex array","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/exposure.ts","lineNumber":182,"sourceCode":"\treturn texture;\n};\n\nconst setupExposure = (target: HTMLCanvasElement): ExposureState => {\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('exposure effect');\n\t}\n\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);\n\n\tconst program = createProgram(gl);\n\tconst vao = gl.createVertexArray();\n\tif (!vao) {\n\t\tthrow new Error('Failed to create exposure vertex array');\n\t}\n\n\tconst vbo = gl.createBuffer();\n\tif (!vbo) {\n\t\tthrow new Error('Failed to create exposure vertex buffer');\n\t}\n\n\tgl.bindVertexArray(vao);\n\tgl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n\tgl.bufferData(\n\t\tgl.ARRAY_BUFFER,\n\t\tnew Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]),\n\t\tgl.STATIC_DRAW,\n\t);\n\n\tconst aPos = gl.getAttribLocation(program, 'aPos');\n\tconst aUv = gl.getAttribLocation(program, 'aUv');\n\tgl.enableVertexAttribArray(aPos);","sourceCodeStart":164,"sourceCodeEnd":200,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/exposure.ts#L164-L200","documentation":"Thrown during setupExposure() when gl.createVertexArray() returns null (exposure.ts:181-183). A null VAO means the driver refused another vertex-array object — context lost or the driver's VAO ceiling reached. Without a VAO the exposure fullscreen-quad attribute state cannot be captured, so setup fails.","triggerScenarios":"setupExposure() 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.","commonSituations":"Compositions stacking numerous WebGL2 effects (each holds a VAO) on a driver with a low VAO cap; 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') which exposes higher, consistent VAO limits.","Reduce concurrent WebGL2 effects in the composition and reuse identical exposure() params (calculateKey caching).","Verify gl.isContextLost() is false and restore the context if needed.","Ensure effect cleanup() runs (it calls gl.deleteVertexArray) so VAOs are recycled.","Update GPU drivers; older drivers leak VAOs across resets."],"exampleFix":"// before\nconst vao = gl.createVertexArray();\nif (!vao) {\n  throw new Error('Failed to create exposure vertex array');\n}\n\n// after (composition-level reuse)\n// share one exposure({stops: x}) across layers instead of one per layer\n// so calculateKey collapses them onto a single canvas/VAO.","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 exposure(); for a custom canvas: const state = setupExposure(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create exposure vertex array') {\n    // reduce concurrent WebGL2 effects, 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 exposure() 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","exposure","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}