remotion-dev/remotion · error

Failed to create LUT shader program

Error message

Failed to create LUT shader program

What it means

gl.createProgram() returned null while setting up the LUT effect's WebGL program, after both shaders compiled. The browser could not allocate a program object, typically due to a lost or resource-exhausted WebGL2 context. This is distinct from a link failure (which produces the 'LUT shader link failed' message).

Solutions

  1. Check canvas' 'webglcontextlost' event and reload/retry the render after 'webglcontextrestored'.
  2. Reduce concurrent WebGL contexts on the page; close other effects/canvases before rendering.
  3. Restart the render, browser, or the machine's GPU process to recover resources.
  4. Ensure hardware acceleration is available (not forced software rendering) in the rendering environment.
Defensive patterns

Strategy: retry

Validate before calling

const gl = canvas.getContext('webgl2');
if (!gl) throw new Error('WebGL2 unavailable');
if (gl.isContextLost()) throw new Error('WebGL2 context already lost — retry later');

Try / catch

try {
  setupEffectWithLut(canvas);
} catch (e) {
  if (e instanceof Error && e.message === 'Failed to create LUT shader program') {
    // release contexts / wait for webglcontextrestored, then retry once
  } else throw e;
}

Prevention

When it happens

Trigger: setupLut -> createProgram calls gl.createProgram() and receives null: the context is lost, the program-object limit is reached, or the driver fails the allocation. Any lut() effect initialization under these conditions.

Common situations: Pages exceeding the browser's live WebGL context limit (commonly ~16 in Chrome); long-running Studio sessions leaking contexts; headless CI renderers running out of GPU/memory resources; GPU process crashes.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/40cdfc1871bf9807. Report an issue: GitHub.

Appendix: source

Thrown at packages/effects/src/lut/lut-runtime.ts:54

	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
		const log = gl.getShaderInfoLog(shader);
		gl.deleteShader(shader);
		throw new Error(`LUT shader compile failed: ${log ?? '(no log)'}`);
	}

	return shader;
};

const createProgram = (gl: WebGL2RenderingContext): WebGLProgram => {
	const vertexShader = compileShader(gl, gl.VERTEX_SHADER, LUT_VERTEX_SHADER);
	const fragmentShader = compileShader(
		gl,
		gl.FRAGMENT_SHADER,
		LUT_FRAGMENT_SHADER,
	);
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create LUT shader program');
	}

	gl.attachShader(program, vertexShader);
	gl.attachShader(program, fragmentShader);
	gl.linkProgram(program);
	gl.deleteShader(vertexShader);
	gl.deleteShader(fragmentShader);

	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const log = gl.getProgramInfoLog(program);
		gl.deleteProgram(program);
		throw new Error(`LUT shader link failed: ${log ?? '(no log)'}`);
	}

	return program;
};

const createSourceTexture = (gl: WebGL2RenderingContext): WebGLTexture => {

View on GitHub (pinned to 46a3a6bf13)