remotion-dev/remotion · error · Error

Unknown program link error

Error message

Unknown program link error

What it means

When the white noise program fails gl.LINK_STATUS, the effect reads gl.getProgramInfoLog; if that returns null it throws the literal 'Unknown program link error'. The vertex/fragment shaders and program object are library-internal constants, so a link failure with no diagnostic points to a driver/compiler bug or context loss during linking — not to user input or GLSL the caller controls.

Source

Thrown at packages/effects/src/white-noise.ts:145

	fragmentSource: string,
): WebGLProgram => {
	const vertex = compileShader(gl, gl.VERTEX_SHADER, vertexSource);
	const fragment = compileShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
	const program = gl.createProgram();
	if (!program) {
		throw new Error('Failed to create program');
	}

	gl.attachShader(program, vertex);
	gl.attachShader(program, fragment);
	gl.linkProgram(program);
	gl.deleteShader(vertex);
	gl.deleteShader(fragment);

	if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
		const info = gl.getProgramInfoLog(program) ?? 'Unknown program link error';
		gl.deleteProgram(program);
		throw new Error(info);
	}

	return program;
};

const createWhiteNoiseState = (
	gl: WebGL2RenderingContext,
	vertexSource: string,
	fragmentSource: string,
): WhiteNoiseState => {
	const program = createProgram(gl, vertexSource, fragmentSource);
	const vao = gl.createVertexArray();
	const vbo = gl.createBuffer();
	const texture = gl.createTexture();

	if (!vao || !vbo || !texture) {
		throw new Error('Failed to create WebGL resources');
	}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render headless with Remotion's bundled Chromium and its known-good SwiftShader; do not pass --disable-gpu.
  2. Update or replace GPU drivers, especially on the failing host.
  3. Ensure the context is not lost before linking (isContextLost()) and re-mount on webglcontextlost.
  4. Lower concurrent WebGL effects to avoid memory pressure during link.
  5. If isolated to one GPU vendor, file a driver bug — the shaders are valid GLSL-ES 3.00.
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot prevent a driver linker failure-with-no-log from the caller.
// Pre-check context health and use a known-good renderer.
const gl = document.createElement('canvas').getContext('webgl2');
const ok = gl != null && !gl.isContextLost();

Type guard

const contextLooksHealthy = (): boolean => {
  const gl = document.createElement('canvas').getContext('webgl2');
  return gl != null && !gl.isContextLost();
};

Try / catch

try {
  return <VideoEffects effects={[whiteNoise({amount: 0.4})]} />;
} catch (err) {
  if (err instanceof Error && err.message === 'Unknown program link error') {
    return <Video />; // driver linker fault; skip the effect
  }
  throw err;
}

Prevention

When it happens

Trigger: createProgram in white-noise.ts: getProgramParameter(LINK_STATUS) is false AND getProgramInfoLog returns null/empty, triggering the fallback throw.

Common situations: Driver linker that fails silently on GLSL-ES 3.00 (#version 300 es) programs; context lost mid-link; software renderer with incomplete program linking; GPU memory exhaustion during link.

Related errors


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