remotion-dev/remotion · error · Error

Failed to create WebGL buffer

Error message

Failed to create WebGL buffer

What it means

Thrown during setupEvolve() when gl.createBuffer() returns null (evolve.ts:280-282). A null VBO means the GL driver declined to allocate another buffer object — context lost or buffer/VBO pool exhausted. The fullscreen-quad vertex data has nowhere to live, so evolve setup fails.

Source

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

	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');
	gl.enableVertexAttribArray(aPos);
	gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);
	gl.enableVertexAttribArray(aUv);
	gl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);

	gl.bindVertexArray(null);

	const textureSource = createRgbaTexture(gl);

	return {
		gl,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render with --gl=angle (CLI) / chromiumOptions.gl='angle' (SSR) / Angle (Studio) for reliable buffer allocation.
  2. Make sure effect lifecycles call cleanup() (it invokes gl.deleteBuffer); don't retain stale evolve states.
  3. Lower the simultaneous WebGL2 effect count in the composition and reuse identical evolve() params (calculateKey caching).
  4. Check gl.isContextLost() and restore the context before retrying.
  5. Use a render host with adequate GPU memory or a stable software GL path.

Example fix

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

// after (defensive caller check)
if (gl.isContextLost()) {
  throw new Error('evolve setup aborted: WebGL2 context lost');
}
Defensive patterns

Strategy: try-catch

Validate before calling

const canAllocateBuffer = (gl: WebGL2RenderingContext): boolean => {
  if (gl.isContextLost()) return false;
  const probe = gl.createBuffer();
  if (!probe) return false;
  gl.deleteBuffer(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 buffer') {
    // free other effects, restore context, retry on Angle
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: evolve() setup runs on a lost WebGL2 context, or the driver has run out of buffer objects due to leaked VBOs from effects whose cleanup() never ran. The guard is the `if (!vbo)` check after the VAO is bound.

Common situations: Long-running Studio sessions accumulating un-cleaned effect canvases; compositions rendering dozens of WebGL2 effects at once; headless CI with constrained GPU resources; post-GPU-crash contexts that report lost.

Related errors


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