remotion-dev/remotion · error · Error

Could not create the LUT preview canvas.

Error message

Could not create the LUT preview canvas.

What it means

After the LUT and sample image load, LutPreview draws to the before/after <canvas> elements via getContext('2d'). If either canvas ref is unmounted or its 2D context cannot be created (e.g. the canvas was replaced, or the browser already assigned a different context type), this error is thrown.

Solutions

  1. Ensure the abort check (controller.signal.aborted) runs right before canvas access; re-check after image.decode() and LUT parse.
  2. Verify nothing calls getContext('webgl'/'bitmaprenderer') on the before/after canvases before '2d'.
  3. Reproduce with React StrictMode disabled to confirm it is a mount/unmount race, then guard with a mountedRef.
  4. Update Studio to the latest version if this occurs spontaneously during normal preview use.

Example fix

// before
const before = beforeRef.current?.getContext('2d');
// after
if (controller.signal.aborted) return;
const before = beforeRef.current?.getContext('2d');
Defensive patterns

Strategy: type-guard

Validate before calling

if (!beforeRef.current || !afterRef.current) return; // skip drawing when unmounted

Type guard

const get2d = (c: HTMLCanvasElement | null): CanvasRenderingContext2D | null =>
  c ? c.getContext('2d') : null;

Try / catch

try {
  drawPreview();
} catch (e) {
  if (e.message === 'Could not create the LUT preview canvas.') return; // unmounted race
  throw e;
}

Prevention

When it happens

Trigger: The load() flow completes after the component unmounted or re-rendered such that beforeRef/afterRef.current is null or the canvas getContext('2d') returns null — typically due to an aborted-but-completed race or calling getContext with a different context type earlier.

Common situations: Fast toggling of the LUT preview panel mid-load; React StrictMode double-mounting racing with the async load; custom code calling getContext('webgl') on the same canvas first.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/dadcd464795a6819. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio/src/components/LutPreview.tsx:201

			}

			image.src = sampleImage;
			try {
				await image.decode();
			} catch {
				throw new Error(
					'Could not load the LUT sample image. Check your internet connection.',
				);
			}

			if (controller.signal.aborted) {
				return;
			}

			const before = beforeRef.current?.getContext('2d');
			const after = afterRef.current?.getContext('2d');
			if (!before || !after) {
				throw new Error('Could not create the LUT preview canvas.');
			}

			before.drawImage(image, 0, 0, previewWidth, previewHeight);
			const pixels = before.getImageData(0, 0, previewWidth, previewHeight);
			applyCubeLut(pixels.data, lut);
			after.putImageData(pixels, 0, 0);
			setState({type: 'loaded'});
		};

		load().catch((error: unknown) => {
			if (!controller.signal.aborted) {
				setState({
					type: 'error',
					error: error instanceof Error ? error.message : String(error),
				});
			}
		});

View on GitHub (pinned to 46a3a6bf13)