remotion-dev/remotion · error · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

Thrown by compileShader in progressive-pixelate-runtime.ts when gl.createShader() returns null during setupProgressivePixelate. Same root cause as the pixelate equivalent (GL cannot allocate a shader object — context lost or exhausted), but for the progressive-pixelate effect which uses a more complex GLSL program.

Source

Thrown at packages/effects/src/progressive-pixelate-runtime.ts:127

	float lowerBlockSize = exp2(floor(level));
	float upperBlockSize = lowerBlockSize * 2.0;
	float levelProgress = fract(level);
	fragColor = mix(
		samplePixelated(lowerBlockSize),
		samplePixelated(upperBlockSize),
		levelProgress
	);
}
`;

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(
			`Progressive pixelate shader compile failed: ${log ?? '(no log)'}`,
		);
	}

	return shader;
};

const linkProgram = (
	gl: WebGL2RenderingContext,
	vs: WebGLShader,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Probe shader allocation in the target environment before mounting progressive pixelate.
  2. Use the published Remotion Lambda Chrome layer with SwiftShader enabled.
  3. Reduce concurrent WebGL2 effects.
  4. Handle 'webglcontextlost' and remount on 'webglcontextrestored'.
  5. Update the GPU driver on reproducible machines.

Example fix

// before
import {setupProgressivePixelate} from '@remotion/effects/progressive-pixelate-runtime';
setupProgressivePixelate(canvas);

// after — probe first
function canCompileShader(gl: WebGL2RenderingContext): boolean {
  const s = gl.createShader(gl.VERTEX_SHADER);
  if (s) gl.deleteShader(s);
  return s !== null;
}
Defensive patterns

Strategy: try-catch

Validate before calling

function glCanCreateShader(gl: WebGL2RenderingContext): boolean {
  if (gl.isContextLost()) return false;
  const s = gl.createShader(gl.VERTEX_SHADER);
  if (s) gl.deleteShader(s);
  return s !== null;
}

Try / catch

try {
  setupProgressivePixelate(canvas);
} catch (err) {
  if (/Failed to create WebGL shader/.test((err as Error).message)) {
    // report WebGL2 unavailable; fall back
  }
  throw err;
}

Prevention

When it happens

Trigger: setupProgressivePixelate() calls compileShader for VERTEX_SHADER or FRAGMENT_SHADER; gl.createShader(type) returns null before any GLSL source is loaded.

Common situations: Headless Chrome/SwiftShader without working shader allocation; context lost before setup; many effects compiled in one tab; virtualized GPU with a low shader cap.

Related errors


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