remotion-dev/remotion · error · Error

Program link failed

Error message

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

What it means

The region-blur runtime links compiled vertex and fragment shaders into a GPU program via gl.linkProgram. If LINK_STATUS is false after linking, the effect deletes the program and throws with the driver's info log. Link failures occur when individually-valid shaders have incompatible interfaces or exceed driver limits at link time.

Solutions

  1. Read the info log to find the mismatched varying, attribute, or exceeded limit
  2. Update GPU drivers to resolve known link-time false negatives
  3. If a limit is exceeded, reduce shader complexity
  4. Report the issue with driver details and the info log
Defensive patterns

Strategy: try-catch

Try / catch

try {
  regionBlur({ topLeft: [0.2, 0.2], bottomRight: [0.8, 0.8] });
} catch (err) {
  if (err instanceof Error && err.message.includes('Program link failed')) {
    console.error('GPU program link failed for regionBlur:', err.message);
  }
  throw err;
}

Prevention

When it happens

Trigger: Varying declarations differ between vertex and fragment shaders; the combined program exceeds the driver's maximum uniform/varying count; shader stages use inconsistent precision qualifiers that the driver rejects at link time.

Common situations: Effect source code changes that break the varying contract between stages; stricter link-time validation on certain mobile drivers; GPU memory pressure causing false link failures.

Related errors


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

Appendix: source

Thrown at packages/effects/src/region-blur/region-blur-runtime.ts:122

	vertexSource: string,
	fragmentSource: string,
): WebGLProgram => {
	const vertexShader = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
	const fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create WebGL 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(`Program link failed: ${log ?? '(no log)'}`);
	}

	return program;
};

const createTexture = (gl: WebGL2RenderingContext): WebGLTexture => {
	const texture = gl.createTexture();
	if (!texture) {
		throw new Error('Failed to create WebGL texture');
	}

	gl.bindTexture(gl.TEXTURE_2D, texture);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
	gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
	gl.bindTexture(gl.TEXTURE_2D, null);
	return texture;

View on GitHub (pinned to 78fe4bb3fd)