remotion-dev/remotion · error · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

Thrown by compileShader in radial-progressive-blur-runtime.ts when gl.createShader() returns null during setupRadialProgressiveBlur. Same allocation-failure family as the other effects' shader errors, specific to the radial-progressive-blur effect (which compiles two programs — horizontal and vertical).

Source

Thrown at packages/effects/src/radial-progressive-blur/radial-progressive-blur-runtime.ts:42

	readonly programHorizontal: WebGLProgram;
	readonly programVertical: WebGLProgram;
	readonly vao: WebGLVertexArrayObject;
	readonly vbo: WebGLBuffer;
	readonly textureSource: WebGLTexture;
	readonly textureIntermediate: WebGLTexture;
	readonly framebuffer: WebGLFramebuffer;
	readonly horizontal: RadialProgressiveBlurUniforms;
	readonly vertical: RadialProgressiveBlurUniforms;
};

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(
			`Radial progressive blur 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 radialProgressiveBlur.
  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 {radialProgressiveBlur} from '@remotion/effects';
const effect = radialProgressiveBlur();

// after — detect shader allocation before mounting
function canCompileShader(gl: WebGL2RenderingContext): boolean {
  const s = gl.createShader(gl.VERTEX_SHADER);
  if (s) gl.deleteShader(s);
  return s !== null && !gl.isContextLost();
}
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 {
  radialProgressiveBlur();
} catch (err) {
  if (/Failed to create WebGL shader/.test((err as Error).message)) {
    // report WebGL2 unavailable; fall back to a non-GPU effect
  }
  throw err;
}

Prevention

When it happens

Trigger: setupRadialProgressiveBlur calls compileShader for the horizontal or vertical pass; gl.createShader(type) returns null before any GLSL source is loaded.

Common situations: Headless Chrome without working shader allocation; context lost before setup; many WebGL2 effects compiled in one tab; virtualized GPU with a low shader-object cap; SwiftShader under load on Lambda.

Related errors


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