remotion-dev/remotion · critical · Error

Failed to create WebGL shader

Error message

Failed to create WebGL shader

What it means

Thrown from lightTrail's WebGL2 setup when `gl.createShader(type)` returns `null`. Per the WebGL spec a non-null return only fails under context loss, GL_OUT_OF_MEMORY, or an implementation that has run out of object handles — the shader source has not even been set yet at this point.

Source

Thrown at packages/effects/src/light-trail/light-trail-runtime.ts:36

		readonly uDistance: WebGLUniformLocation | null;
		readonly uIntensity: WebGLUniformLocation | null;
		readonly uDecay: WebGLUniformLocation | null;
		readonly uThreshold: WebGLUniformLocation | null;
		readonly uSamples: WebGLUniformLocation | null;
	};
	readonly colorCtx: CanvasRenderingContext2D;
	cachedColorStr: string;
	cachedColorRgba: ParsedColorRgba;
};

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(`Light trail 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. Register a `webglcontextlost` listener on the canvas and surface a user-facing error or reload the composition rather than retrying blindly.
  2. Reduce the number of simultaneously active WebGL effects in the frame; share or cache effect state across frames (the effect already keys by params in its setup cache).
  3. In headless rendering, ensure the Chrome build has GPU available (Lambda uses a real GPU layer) and avoid `--disable-gpu`.
  4. If context loss is the cause, dispose and recreate the effect's setup once the `webglcontextrestored` event fires.
  5. Update GPU drivers / Mesa on self-hosted render workers.

Example fix

// before
const state = setupLightTrail(canvas);

// after
canvas.addEventListener('webglcontextlost', (e) => {
  e.preventDefault();
  cleanupLightTrail(prevState);
  reportRenderError('lightTrail unavailable: WebGL context lost');
}, { once: true });
try {
  const state = setupLightTrail(canvas);
} catch (err) {
  // fall back to a non-WebGL composition branch
}
Defensive patterns

Strategy: fallback

Validate before calling

const webgl2Available = (canvas: HTMLCanvasElement): boolean => {
  try {
    return !!canvas.getContext('webgl2');
  } catch {
    return false;
  }
};

Type guard

const supportsWebGL2 = (): boolean => {
  try {
    const c = document.createElement('canvas');
    return !!c.getContext('webgl2');
  } catch {
    return false;
  }
};

Try / catch

let state;
try {
  state = setupLightTrail(canvas);
} catch (err) {
  // WebGL2 can't allocate right now — render without the effect.
  console.error('lightTrail unavailable, falling back', err);
  state = null;
}

Prevention

When it happens

Trigger: Setting up many lightTrail (or other WebGL) effects concurrently until the GL driver runs out of shader handles; a context-loss event firing mid-setup; rendering in a headless/Chromium-for-Testing build with software rendering that refuses object creation; running after a previous GL error left the context in a lost state.

Common situations: Rendering long videos with dozens of stacked effects on one frame; CI/headless Chrome with `--disable-gpu` but WebGL2 still nominally supported; older Linux Mesa drivers; remotion-lambda Chrome hitting a transient GL reset; reopening Studio many times in a session that leaks contexts.

Related errors


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