remotion-dev/remotion · critical · Error

Program link failed: ${log ?? '(no log)'}

Error message

Program link failed: ${log ?? '(no log)'}

What it means

The zoomBlur shader program failed to link, meaning the vertex and fragment shaders compiled individually but their interfaces (varyings, attribute locations) are incompatible. Since both shaders are internal constants, a link failure points to a GPU driver bug in the linker rather than a user error. The driver's info log is included.

Source

Thrown at packages/effects/src/zoom-blur/zoom-blur-runtime.ts:58

};

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

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

	return program;
};

const createProgram = (
	gl: WebGL2RenderingContext,
	vertexSource: string,
	fragmentSource: string,
): WebGLProgram => {
	const vs = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
	const fs = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
	const program = linkProgram(gl, vs, fs);
	gl.deleteShader(vs);
	gl.deleteShader(fs);
	return program;
};

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Update the GPU driver or the browser/SwiftShader version.
  2. Test on a different GPU to confirm driver-specific behavior.
  3. Report the issue to Remotion with the program info log from the error message.
  4. On CI, use a Docker image with a known-good GL stack.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  zoomBlur({ amount: 40 });
} catch (err) {
  if (err instanceof Error && err.message.startsWith('Program link failed')) {
    console.error('Program link failed on this GPU:', err.message);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: A driver bug where the vertex shader's output varyings do not match the fragment shader's inputs due to a precision or naming discrepancy in the driver's internal representation, or drivers with incomplete GLSL ES 3.00 linking support.

Common situations: Older mobile GPUs, virtualized graphics, headless rendering with incomplete WebGL2 driver support, or a GPU driver version with a known linker regression.

Related errors


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