remotion-dev/remotion · error · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

Thrown by `compileShader` in the barrel-distortion WebGL runtime when `gl.createShader(type)` returns null. A null return indicates the WebGL2 context could not allocate a shader object — typically because the context is lost, the context is not actually a WebGL2 context, or too many resources are allocated. The check happens before shaderSource/compile.

Source

Thrown at packages/effects/src/barrel-distortion/barrel-distortion-runtime.ts:28

	gl: WebGL2RenderingContext;
	program: WebGLProgram;
	vao: WebGLVertexArrayObject;
	vbo: WebGLBuffer;
	textureSource: WebGLTexture;
	uniforms: {
		uSource: WebGLUniformLocation | null;
		uAmount: WebGLUniformLocation | null;
	};
};

const compileShader = (
	gl: WebGL2RenderingContext,
	type: number,
	source: string,
): WebGLShader => {
	const shader = gl.createShader(type);
	if (!shader) {
		throw new Error('Failed to create WebGL shader');
	}

	gl.shaderSource(shader, source);
	gl.compileShader(shader);
	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
		const log = gl.getShaderInfoLog(shader);
		gl.deleteShader(shader);
		throw new Error(`Shader compile failed: ${log ?? '(no log)'}`);
	}

	return shader;
};

const linkProgram = (
	gl: WebGL2RenderingContext,
	vs: WebGLShader,
	fs: WebGLShader,
): WebGLProgram => {

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Ensure the canvas acquires a `webgl2` context and handle `webglcontextlost` by recreating the effect state.
  2. Run the render on an environment with WebGL2 support (Chromium with GPU, or SwiftShader).
  3. Reduce the number of concurrent WebGL effect instances to stay within GPU memory.
  4. Retry the render on context restore rather than failing immediately.

Example fix

// before
effect.init(canvas); // createShader returned null

// after
canvas.addEventListener('webglcontextrestored', () => effect.init(canvas));
canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());
Defensive patterns

Strategy: validation

Validate before calling

const gl = canvas.getContext('webgl2');
if (!gl) throw new Error('WebGL2 unavailable');
const shader = gl.createShader(gl.VERTEX_SHADER);
if (!shader) throw new Error('context may be lost; recreate it');

Type guard

const hasValidWebGL2 = (canvas: HTMLCanvasElement): boolean =>
  canvas.getContext('webgl2') instanceof WebGL2RenderingContext;

Try / catch

try {
  effect.init(canvas);
} catch (e) {
  if (/Failed to create WebGL shader/.test(String(e))) {
    await waitForContextRestore(canvas); effect.init(canvas);
  } else throw e;
}

Prevention

When it happens

Trigger: The barrel-distortion effect's `compileShader` is called on a WebGL2RenderingContext that is lost or invalid, so `createShader` yields null. This can occur when the canvas context was lost (webglcontextlost event), the GPU process crashed, or the context was retrieved as WebGL1 by mistake.

Common situations: Rendering the barrel-distortion effect on a machine/driver with flaky WebGL2; context loss during a long render; running in a headless browser without GPU/WebGL2 support; too many simultaneous effect instances exhausting GPU memory.

Related errors


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