remotion-dev/remotion · error · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

Thrown by the compileShader() helper of the halftone WebGL2 effect when gl.createShader(type) returns null. A null shader means the GL implementation refused to allocate a shader object — object-budget exhaustion or context loss — before any source is even attached. The effect has not yet attempted to compile, so no info log exists.

Solutions

  1. Check gl.isContextLost() and restart the render if true.
  2. Reduce the number of WebGL2 effects in flight per render.
  3. Render on a machine with a healthier GPU/driver.
  4. Restart Chrome/Studio to clear leaked GL objects.
Defensive patterns

Strategy: try-catch

Validate before calling

// Probe whether the context will allocate a shader object.
function canCreateShader(canvas: HTMLCanvasElement): boolean {
  const gl = canvas.getContext('webgl2');
  if (!gl) return false;
  const s = gl.createShader(gl.VERTEX_SHADER);
  const ok = s !== null;
  if (s) gl.deleteShader(s);
  return ok;
}

Try / catch

try {
  // ...use halftone()
} catch (e) {
  if (e instanceof Error && /Failed to create WebGL shader/.test(e.message)) {
    // shader object budget exhausted or context lost; restart render
  } else throw e;
}

Prevention

When it happens

Trigger: setup() of the halftone effect running when the GL context is lost or its shader object budget is exhausted; rendering on a GPU/driver whose shader object limit is unusually low.

Common situations: Long render sessions allocating many WebGL2 effects; GPU process crash leaving a zombie context; integrated GPUs under heavy load.

Related errors


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

Appendix: source

Thrown at packages/effects/src/halftone.ts:357

	colorCtx: CanvasRenderingContext2D;
	cachedColorStr: string;
	cachedColorRgba: ParsedColorRgba;
};

const SHAPE_INDEX: Record<HalftoneShape, number> = {
	circle: 0,
	square: 1,
	line: 2,
};

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

	return shader;
};

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

View on GitHub (pinned to 78fe4bb3fd)