remotion-dev/remotion · critical · Error

Failed to create WebGL vertex array

Error message

Failed to create WebGL vertex array

What it means

Thrown by setupWave() when gl.createVertexArray() returns null. A vertex array object (VAO) creation returns null only on context loss, context destruction, or GPU resource exhaustion. This is a low-level WebGL allocation failure that prevents the wave effect from setting up its geometry bindings.

Source

Thrown at packages/effects/src/wave/wave-runtime.ts:122

export const setupWave = (target: HTMLCanvasElement): WaveState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('wave effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
	gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);

	const program = createProgram(gl, WAVE_VS, WAVE_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);

	gl.enableVertexAttribArray(0);
	gl.vertexAttribPointer(0, 2, gl.FLOAT, false, 16, 0);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Listen for the 'webglcontextlost' event on the canvas and recreate the context (and re-run setupWave) on 'webglcontextrestored'.
  2. Reduce the number of concurrent effect instances to free VAO slots.
  3. Ensure prior effect states are cleaned up (cleanupWave) before creating new canvases.
  4. Update GPU drivers or switch render environments (e.g., use a different Chrome/Chromium build for headless rendering).

Example fix

// before
canvas.addEventListener('webglcontextlost', (e) => {
  // no handler — context lost silently, subsequent setup throws
});
const state = setupWave(canvas);

// after
canvas.addEventListener('webglcontextlost', (e) => {
  e.preventDefault(); // allow restoration
});
canvas.addEventListener('webglcontextrestored', () => {
  state = setupWave(canvas); // re-initialize on restore
});
Defensive patterns

Strategy: try-catch

Try / catch

const gl = canvas.getContext('webgl2');
if (!gl || gl.isContextLost()) {
  return; // skip setup on lost context
}
try {
  const state = setupWave(canvas);
} catch (e) {
  if ((e as Error).message === 'Failed to create WebGL vertex array') {
    console.warn('VAO allocation failed — possible context loss:', (e as Error).message);
  }
}

Prevention

When it happens

Trigger: Called from setupWave() at packages/effects/src/wave/wave-runtime.ts:120 after the program is created. Fires when the GL context is lost or the GPU cannot allocate another VAO. Since the program was already created successfully, this is a progressive resource exhaustion or a context-loss event that occurred between program creation and VAO creation.

Common situations: WebGL context lost event fired mid-setup; GPU memory exhausted from many concurrent effect canvases; running in a constrained environment (mobile GPU, older integrated graphics, virtual machine); browser tab GPU process instability.

Related errors


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