remotion-dev/remotion · critical · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

A plain Error thrown inside compileShader in the Liquid contours effect when gl.createShader(type) returns null. Identical contract to the Lines effect: WebGL2 may return null under resource exhaustion or context loss, and the effect aborts instead of dereferencing null.

Source

Thrown at packages/effects/src/liquid-contours.ts:287

	float detailedField = fbm(p + warp * mix(0.35, 1.8, uComplexity));
	float detailMix = smoothstep(0.0, 1.0, uComplexity);
	float field = mix(roundedField, detailedField, detailMix);
	float levels = max(max(uResolution.x, uResolution.y) / max(uSpacing, 0.001), 1.0);
	float wave = sin((field * levels + uPhase) * 6.28318530718);
	float edgeWidth = fwidth(wave) * mix(0.15, 1.4, uSmoothness);
	float selector = smoothstep(-edgeWidth, edgeWidth, wave);
	vec4 color = mix(uFirstColor, uSecondColor, selector);
	fragColor = vec4(color.rgb * color.a, color.a);
}
`;

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

	return shader;
};

const createProgram = (gl: WebGL2RenderingContext): WebGLProgram => {
	const vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);
	const fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);
	const program = gl.createProgram();
	if (!program) throw new Error('Failed to create WebGL program');

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Reduce concurrent browser contexts / render parallelism.
  2. Confirm the host WebGL2 stack is healthy with a smoke test.
  3. Handle webglcontextlost / webglcontextrestored and re-instantiate the effect.
Defensive patterns

Strategy: try-catch

Validate before calling

function webgl2Ready(): boolean {
  const c = document.createElement('canvas');
  const gl = c.getContext('webgl2');
  const ok = !!gl && !!gl.createShader(gl.VERTEX_SHADER);
  return ok;
}

Try / catch

try {
  liquidContours(...);
} catch (err) {
  if (err instanceof Error && /WebGL shader/.test(err.message)) {
    // fall back or surface 'GPU unavailable'
  } else throw err;
}

Prevention

When it happens

Trigger: The WebGL2 context exists (passed the earlier createWebGL2ContextError check for 'liquid contours effect') but cannot allocate a shader object. GPU memory exhaustion, too many live shaders, or a lost context.

Common situations: Many concurrent Remotion renders; a page that leaked GL objects; headless software GL with a small budget; transient context-loss during a long render.

Related errors


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