remotion-dev/remotion · error · Error

Failed to create WebGL program

Error message

Failed to create WebGL program

What it means

The skew() effect acquired a WebGL2 context and compiled both shaders, but gl.createProgram() returned null in setupSkew(). A null program object means the context lost resources or hit a driver-imposed program limit, so the effect cannot link its vertex/fragment shaders and throws before continuing.

Source

Thrown at packages/effects/src/skew.ts:193

	return shader;
};

const setupSkew = (target: HTMLCanvasElement): SkewState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {
		throw createWebGL2ContextError('skew effect');
	}

	gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
	const vertexShader = compileShader(gl, gl.VERTEX_SHADER, SKEW_VS);
	const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, SKEW_FS);
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create WebGL program');
	}

	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);
	gl.deleteShader(vertexShader);
	gl.deleteShader(fragmentShader);
	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const log = gl.getProgramInfoLog(program);
		gl.deleteProgram(program);
		throw new Error(`Skew program link failed: ${log ?? '(no log)'}`);
	}

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

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Use the ANGLE backend (--gl=angle / chromiumOptions.gl='angle' / Studio OpenGL=angle) for more reliable program allocation.
  2. Reduce concurrency and the count of simultaneously-active WebGL2 effects to stay under driver resource limits.
  3. Ensure effect cleanup (gl.deleteProgram etc.) runs so program handles are freed before new effects allocate them.
  4. Render on a host with a supported GPU and up-to-date drivers.

Example fix

// before
await renderMedia({ composition, serveUrl });

// after
await renderMedia({ composition, serveUrl, chromiumOptions: { gl: 'angle' } });
Defensive patterns

Strategy: try-catch

Validate before calling

// No caller-side check can predict a null gl.createProgram().
// Best pre-flight is generic WebGL2 capability (see error 900).
function webgl2Available(): boolean {
  try {
    return !!document.createElement('canvas').getContext('webgl2');
  } catch {
    return false;
  }
}

Try / catch

try {
  await renderMedia({ composition, codec: 'h264', chromiumOptions: { gl: 'angle' } });
} catch (err) {
  if (err instanceof Error && /Failed to create WebGL program/.test(err.message)) {
    console.error('skew() could not allocate a WebGL program (context lost/exhausted). Lower concurrency or switch GL backend.', err);
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: Context loss or GPU resource exhaustion occurring between shader compilation and program creation inside setupSkew(); a driver that imposes a low ceiling on simultaneously-live program objects when many WebGL2 effects are initialized.

Common situations: Many stacked WebGL2 effects per composition combined with high render concurrency; long-running renders that gradually exhaust driver resources; headless/CI hosts without a real GPU; driver reset mid-setup.

Related errors


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