remotion-dev/remotion · error

Failed to create output canvas context

Error message

Failed to create output canvas context

What it means

In @remotion/transitions' HTML-in-canvas presentation, clearOutput obtains a 2D rendering context from the output canvas via getContext('2d') to clear it between draws. If the browser returns null — no 2D context can be created — this error is thrown inside the onPaint delayRender scope. This typically means the canvas is already bound to a different context type or the canvas cannot provide a context at all.

Source

Thrown at packages/transitions/src/html-in-canvas-presentation.tsx:120

		};
	}, [instance]);

	const chainState = Internals.useEffectChainState();
	const {delayRender, continueRender, cancelRender} = useDelayRender();

	const draw: DrawFunction = useCallback(
		async (prevImage, nextImage, progress) => {
			const outputCanvas = outputCanvasRef.current;
			if (!outputCanvas) {
				throw new Error('Canvas not found');
			}

			const handle = delayRender('onPaint');
			try {
				const clearOutput = () => {
					const context = outputCanvas.getContext('2d');
					if (!context) {
						throw new Error('Failed to create output canvas context');
					}

					context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
				};

				if (!prevImage && !nextImage) {
					instance.clear();
					clearOutput();
					continueRender(handle);
					return;
				}

				const width = prevImage?.width ?? nextImage?.width ?? 0;
				const height = prevImage?.height ?? nextImage?.height ?? 0;

				if (width === 0 || height === 0) {
					instance.clear();
					clearOutput();

View on GitHub (pinned to a6a7485a9a)

Solutions

  1. Ensure nothing else calls getContext with a non-2d type on the same outputCanvas; give the presentation its own dedicated canvas element
  2. Create a fresh canvas for the presentation instead of reusing one from elsewhere in the app
  3. Verify the code runs in a browser with a real DOM document (not SSR) and the canvas is attached/has non-zero width/height
  4. Enable GPU/hardware acceleration (or add --enable-unsafe-swiftshader / software GL flags) in headless Chrome if context creation fails there
  5. Wrap the paint work so the error surfaces with the delayRender handle properly released (use continueRender in a catch/finally) to avoid a stuck render

Example fix

// before
const context = outputCanvas.getContext('2d'); // null if canvas already used for webgl
if (!context) throw new Error('Failed to create output canvas context');
// after
const outputCanvas = document.createElement('canvas'); // dedicated canvas, never handed to webgl
const context = outputCanvas.getContext('2d');
if (!context) throw new Error('Failed to create output canvas context');
Defensive patterns

Strategy: try-catch

Validate before calling

function canProvide2DContext(canvas: HTMLCanvasElement): boolean {
  // A canvas can only ever yield one context type; probe safely by checking existing state.
  return canvas instanceof HTMLCanvasElement && canvas.width > 0 && canvas.height > 0;
}

Type guard

function has2DContext(canvas: HTMLCanvasElement): canvas is HTMLCanvasElement & { getContext: (t: '2d') => CanvasRenderingContext2D } {
  return canvas.getContext('2d') !== null;
}

Try / catch

const handle = delayRender('onPaint');
try {
  const context = outputCanvas.getContext('2d');
  if (!context) throw new Error('Failed to create output canvas context');
  context.clearRect(0, 0, outputCanvas.width, outputCanvas.height);
  continueRender(handle);
} catch (err) {
  continueRender(handle);
  console.error('Canvas 2D context unavailable; use a fresh dedicated canvas.', err);
}

Prevention

When it happens

Trigger: Calling getContext('2d') on a canvas that previously had getContext('webgl'/'bitmaprenderer') called on it (a canvas returns null for all other context types after the first); passing a detached/off-DOM or zero-sized canvas in an environment without a real document; browser failing context creation under memory pressure.

Common situations: Mixing the transitions canvas presentation with other code (three.js, WebGL preview) that grabbed a different context on the same canvas element; rendering headless (server-side) where the canvas is not backed by a document; hardware-acceleration disabled in the rendering browser causing 2D context creation to fail.

Related errors


AI-assisted analysis of remotion-dev/remotion@a6a7485a9a (2026-09-02). Data as JSON: /api/errors/b4fda24c553bf3cf. Report an issue: GitHub.