remotion-dev/remotion · error · Error

Failed to create exposure texture

Error message

Failed to create exposure texture

What it means

Thrown inside createTexture() in exposure.ts when gl.createTexture() returns null (exposure.ts:154-156). A null texture means the driver would not allocate another texture object — context lost or texture pool/GPU memory exhausted. The exposure source sampler has no target, so setup aborts.

Source

Thrown at packages/effects/src/exposure.ts:155

	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(`Exposure shader link failed: ${log ?? '(no log)'}`);
	}

	return program;
};

const createTexture = (gl: WebGL2RenderingContext): WebGLTexture => {
	const texture = gl.createTexture();
	if (!texture) {
		throw new Error('Failed to create exposure 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;
};

const setupExposure = (target: HTMLCanvasElement): ExposureState => {
	const gl = target.getContext('webgl2', {
		premultipliedAlpha: true,
		alpha: true,
		preserveDrawingBuffer: true,
	});
	if (!gl) {

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Render with --gl=angle (CLI) / chromiumOptions.gl='angle' (SSR) / Angle (Studio).
  2. Ensure effect cleanup() runs (it calls gl.deleteTexture on textureSource); never hold stale exposure states.
  3. Cut the simultaneous WebGL2 effect count and reuse identical exposure() params via calculateKey.
  4. Check gl.isContextLost() and restore the context before retrying.
  5. Move to a host with more GPU memory or a consistent software GL path.

Example fix

// before
const texture = gl.createTexture();
if (!texture) {
  throw new Error('Failed to create exposure texture');
}

// after (caller guard)
if (gl.isContextLost()) {
  // defer exposure setup until webglcontextrestored
}
Defensive patterns

Strategy: try-catch

Validate before calling

const canAllocateTexture = (gl: WebGL2RenderingContext): boolean => {
  if (gl.isContextLost()) return false;
  const probe = gl.createTexture();
  if (!probe) return false;
  gl.deleteTexture(probe);
  return true;
};

Try / catch

try {
  // apply exposure(); for a custom canvas: const state = setupExposure(canvas);
} catch (err) {
  if (err instanceof Error && err.message === 'Failed to create exposure texture') {
    // free other effects, restore context, retry on Angle
    throw err;
  }
  throw err;
}

Prevention

When it happens

Trigger: setupExposure() calls createTexture() (the source texture used by uSource) and gl.createTexture() returns null. This occurs when the WebGL2 context is lost or when leaked textures from un-cleaned effects have exhausted the driver's texture-object/memory budget.

Common situations: Long-running Studio sessions leaking textures; compositions with many simultaneous exposure() layers; headless CI hosts with limited GPU memory; contexts left lost after a GPU crash.

Related errors


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