remotion-dev/remotion · error · Error

Failed to create WebGL vertex array

Error message

Failed to create WebGL vertex array

What it means

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.

Source

Thrown at packages/effects/src/evolve.ts:270

		alpha: true,
		preserveDrawingBuffer: true,
	});

	if (!gl) {
		throw createWebGL2ContextError('evolve effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

	const vs = compileShader(gl, gl.VERTEX_SHADER, EVOLVE_VS);
	const fs = compileShader(gl, gl.FRAGMENT_SHADER, EVOLVE_FS);
	const program = linkProgram(gl, vs, fs);
	gl.deleteShader(vs);
	gl.deleteShader(fs);

	const vao = gl.createVertexArray();
	if (!vao) {
		throw new Error('Failed to create WebGL vertex array');
	}

	gl.bindVertexArray(vao);

	const data = new Float32Array([
		-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1,
	]);

	const vbo = gl.createBuffer();
	if (!vbo) {
		throw new Error('Failed to create WebGL buffer');
	}

	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);

	const aPos = gl.getAttribLocation(program, 'aPos');
	const aUv = gl.getAttribLocation(program, 'aUv');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render with the Angle backend (--gl=angle / chromiumOptions.gl='angle') which has higher, more consistent VAO limits.
  2. Cut the number of simultaneous WebGL2 effects in the composition, or share one evolve() instance across layers via identical params so calculateKey reuses state.
  3. Verify the context is healthy with gl.isContextLost() and restore before retrying.
  4. Update GPU drivers; some older drivers leak VAOs across context resets.
  5. On CI, pin a software GL path that is known to handle your effect count.

Example fix

// before
const vao = gl.createVertexArray();
if (!vao) {
  throw new Error('Failed to create WebGL vertex array');
}

// after (composition-level: collapse duplicate effects onto one canvas)
// evolve({progress: 0.5, direction: 'left', feather: 0.1}) // repeated per layer
// -> compute the param set once and reuse the same evolve() reference.
Defensive patterns

Strategy: try-catch

Validate before calling

const canAllocateVao = (gl: WebGL2RenderingContext): boolean => {
  if (gl.isContextLost()) return false;
  const probe = gl.createVertexArray();
  if (!probe) return false;
  gl.deleteVertexArray(probe);
  return true;
};

Try / catch

try {
  // apply evolve(); for a custom canvas: const state = setupEvolve(canvas);
} catch (err) {
  if (err instanceof Error && err.message === 'Failed to create WebGL vertex array') {
    // reduce concurrent WebGL2 effects, then retry on Angle
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/103840f7febc4beb. Report an issue: GitHub.