{"record":{"id":"00cdda1cf32d7e1c","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-vertex-array-00cdda","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/pixelate.ts","lineNumber":132,"sourceCode":"\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\tconst log = gl.getProgramInfoLog(program);\n\t\tgl.deleteProgram(program);\n\t\tthrow new Error(`Pixelate program link failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn program;\n};\n\nconst createPixelateState = (gl: WebGL2RenderingContext): PixelateState => {\n\tconst vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);\n\tconst fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);\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":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/pixelate.ts#L114-L150","documentation":"Thrown by createPixelateState when gl.createVertexArray() returns null after the program was linked. This is the first per-frame-state allocation after program setup; a null VAO means the GL context cannot allocate another vertex array object. The guard prevents bindVertexArray from receiving null.","triggerScenarios":"pixelate() setup: shaders compiled, program linked, then gl.createVertexArray() in createPixelateState returns null.","commonSituations":"Context lost between program link and VAO creation; VAO pool exhausted by many effects; SwiftShader on a memory-constrained Lambda function; integrated GPU with low VAO cap.","solutions":["Verify `gl.isContextLost()` is false before mounting pixelate; remount on restore.","Limit the number of WebGL2 effects active in one composition.","Increase Lambda function memory.","Reproduce on stable desktop Chrome to isolate environment issues.","Free other GPU resources before applying pixelate."],"exampleFix":"// before\nimport {pixelate} from '@remotion/effects';\nconst effect = pixelate();\n\n// after — probe VAO allocation up front\nfunction glCanCreateVao(gl: WebGL2RenderingContext): boolean {\n  if (gl.isContextLost()) return false;\n  const v = gl.createVertexArray();\n  const ok = v !== null;\n  if (v) gl.deleteVertexArray(v);\n  return ok;\n}","handlingStrategy":"try-catch","validationCode":"function glCanCreateVao(gl: WebGL2RenderingContext): boolean {\n  if (gl.isContextLost()) return false;\n  const v = gl.createVertexArray();\n  if (v) gl.deleteVertexArray(v);\n  return v !== null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  pixelate();\n} catch (err) {\n  if (/Failed to create WebGL vertex array/.test((err as Error).message)) {\n    // environment lacks VAO capacity; remount after context restore\n  }\n  throw err;\n}","preventionTips":["Probe VAO allocation in the target environment before mounting.","Handle 'webglcontextlost'/'webglcontextrestored' and remount effects.","Limit concurrent WebGL2 effects in one composition.","Use adequate Lambda function memory."],"tags":["webgl","gpu","pixelate","vao","environment"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}