remotion-dev/remotion · critical · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

During starburst effect `setup`, `gl.createShader()` returned `null`, meaning the WebGL2 implementation could not allocate a new shader object. This typically indicates the GL context has been lost, the GPU/driver is out of resources, or the context is in a degraded state. The error is thrown before any shader source is uploaded.

Source

Thrown at packages/effects/src/starburst.ts:238

	uColorPalette: WebGLUniformLocation | null;
	uNumRays: WebGLUniformLocation | null;
	uRotationOffset: WebGLUniformLocation | null;
	uSmoothEdge: WebGLUniformLocation | null;
	uResolution: WebGLUniformLocation | null;
	uNumColors: WebGLUniformLocation | null;
	uOrigin: WebGLUniformLocation | null;
	cachedPaletteKey: string;
	palettePixelData: Uint8Array;
};

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(`Starburst 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. Reduce the number of concurrent webgl2 effects in the composition to lower GPU resource pressure.
  2. Restart the render or Studio session to obtain a fresh WebGL2 context.
  3. In headless/CI environments, ensure the browser (e.g. Chrome headless) is launched with GPU/WebGL2 enabled flags like `--use-gl=angle --use-angle=swiftshader`.
  4. Check for and handle `webglcontextlost` events on the canvas to proactively recreate contexts.
Defensive patterns

Strategy: fallback

Validate before calling

// Before mounting the effect, probe WebGL2 viability on a scratch canvas.
const supportsWebGL2 = (): boolean => {
  try {
    const c = document.createElement('canvas');
    const gl = c.getContext('webgl2');
    const shader = gl?.createShader(gl.VERTEX_SHADER);
    const ok = !!shader;
    shader && gl!.deleteShader(shader);
    return ok;
  } catch {
    return false;
  }
};
if (!supportsWebGL2()) { /* skip starburst or use a 2d fallback */ }

Try / catch

try {
  starburst({...params});
} catch (e) {
  if (/Failed to create WebGL/.test((e as Error).message)) {
    // context lost / exhausted: skip the effect or requeue the render
    renderFallbackFrame();
  } else throw e;
}

Prevention

When it happens

Trigger: The WebGL2 context was lost (e.g. tab backgrounded, GPU driver reset) before setup ran; too many shader objects already allocated in the page; running in a headless browser with incomplete WebGL2 support; the canvas's GL context was already destroyed.

Common situations: Rendering many starburst (or other webgl2) effect instances concurrently in a single page; long-running Studio sessions where the GPU driver crashes and resets; CI environments using software-rendered WebGL with low resource caps; mobile browsers under memory pressure.

Related errors


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