remotion-dev/remotion · critical · Error

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

Error message

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

What it means

Thrown by the blur effect's `linkProgram` when both shaders compiled but `gl.linkProgram` produced a falsy LINK_STATUS. The message embeds the info log. Blur uses two separable programs (horizontal, vertical) that share BLUR_VS, so a link failure usually traces to a vertex/fragment interface mismatch in the shipped shaders or a driver limitation.

Source

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

};

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. Read the embedded info log for the precise linker diagnostic.
  2. Update @remotion/effects — link regressions are fixed upstream.
  3. Reproduce on another GPU/browser to detect driver-specific linking bugs.
  4. For headless rendering, confirm WebGL2 is hardware-backed and report the GL_RENDERER.

Example fix

// Library-internal shader issue; capture the info log and report upstream.
console.error(gl.getParameter(gl.RENDERER));
Defensive patterns

Strategy: fallback

Validate before calling

// Probe linking with a minimal program before setup.
const p = gl.createProgram();
if (!p) { /* skip */ }
// attach minimal compiled vs/fs, link, check LINK_STATUS, then delete

Try / catch

try {
  const state = setupBlur(canvas);
} catch (err) {
  if (/Program link failed/.test(err.message)) {
    // fall back to a non-WebGL effect; report info log upstream
  } else { throw err; }
}

Prevention

When it happens

Trigger: Fires at line 68 when `gl.getProgramParameter(program, gl.LINK_STATUS)` is falsy after linking either the horizontal or vertical blur program.

Common situations: Shipped shader revision with a varying/in-out mismatch between BLUR_VS and a BLUR_FS_*; driver rejects uniform/attribute declarations; software rasterizer with stricter linking; corrupted shader constants from a bad build.

Related errors


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