remotion-dev/remotion · error · Error

Failed to create white balance vertex array

Error message

Failed to create white balance vertex array

What it means

During white balance setup the effect creates a VAO (gl.createVertexArray) to bind its fullscreen-quad attribute layout. A null return means the WebGL2 implementation could not allocate the vertex-array object, which the effect cannot proceed without because all draw calls depend on that VAO being bound. Like the other null-resource throws, it reflects a degraded/lost GL context rather than bad input.

Source

Thrown at packages/effects/src/white-balance.ts:197

	return texture;
};

const setupWhiteBalance = (target: HTMLCanvasElement): WhiteBalanceState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('white balance effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);

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

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

	gl.bindVertexArray(vao);
	gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
	gl.bufferData(
		gl.ARRAY_BUFFER,
		new Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]),
		gl.STATIC_DRAW,
	);

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

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Confirm the render environment exposes a healthy WebGL2 context (getContext('webgl2') non-null, isContextLost() false).
  2. Use Remotion's bundled Chrome for Lambda/headless rendering instead of a system Chromium that may disable GPU features.
  3. Lower the count of simultaneously-active WebGL effects so the GL object pool is not exhausted.
  4. Handle webglcontextlost and tear down/recreate the composition so setup re-runs against a fresh context.
  5. Update GPU drivers or move off a pure-software rendering backend.
Defensive patterns

Strategy: try-catch

Validate before calling

const gl = document.createElement('canvas').getContext('webgl2');
const webglOk = gl != null && gl.createVertexArray() != null && !gl.isContextLost();

Type guard

const canAllocateVAO = (): boolean => {
  const gl = document.createElement('canvas').getContext('webgl2');
  return gl != null && !gl.isContextLost() && gl.createVertexArray() != null;
};

Try / catch

try {
  return <VideoEffects effects={[whiteBalance({tint: 0.2})]} />;
} catch (err) {
  if (err instanceof Error && /white balance vertex array/.test(err.message)) {
    return <Video />; // degrade gracefully
  }
  throw err;
}

Prevention

When it happens

Trigger: setupWhiteBalance runs on the first frame, calls gl.createVertexArray(), and the context returns null — typically because the context was lost, VAO object limits are hit, or the backend is a software renderer with incomplete WebGL2 support.

Common situations: Rendering in a headless/CI environment with a SwiftShader or blocklisted GPU; many concurrent effect-bearing compositions exhausting GL object quotas; a context-loss event firing mid-session; older virtual/GPU-forwarding setups with partial VAO support.

Related errors


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