remotion-dev/remotion · error · Error

HtmlInCanvas: `height` must be a positive integer. Received:

Error message

HtmlInCanvas: `height` must be a positive integer. Received: ${String(height)}.

What it means

Thrown by assertHtmlInCanvasDimensions when `height` is a number but fails the positive-integer check (zero, negative, fractional, NaN). Symmetric to the width check, it guarantees the canvas backing store has a valid pixel height before allocation.

Source

Thrown at packages/core/src/HtmlInCanvas.tsx:263

) => HtmlInCanvasOnInitCleanup | Promise<HtmlInCanvasOnInitCleanup>;

export type HtmlInCanvasPixelDensity = number;

function assertHtmlInCanvasDimensions(width: unknown, height: unknown): void {
	if (typeof width !== 'number' || typeof height !== 'number') {
		throw new Error(
			`HtmlInCanvas: \`width\` and \`height\` must be numbers. Received width=${String(width)}, height=${String(height)}.`,
		);
	}

	if (!Number.isInteger(width) || width <= 0) {
		throw new Error(
			`HtmlInCanvas: \`width\` must be a positive integer. Received: ${String(width)}.`,
		);
	}

	if (!Number.isInteger(height) || height <= 0) {
		throw new Error(
			`HtmlInCanvas: \`height\` must be a positive integer. Received: ${String(height)}.`,
		);
	}
}

function resolveHtmlInCanvasPixelDensity(
	pixelDensity: HtmlInCanvasPixelDensity | undefined,
): number {
	if (pixelDensity === undefined) {
		return 1;
	}

	if (
		typeof pixelDensity !== 'number' ||
		!Number.isFinite(pixelDensity) ||
		pixelDensity <= 0
	) {
		throw new Error(

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Round and floor-clamp: `Math.max(1, Math.round(value))`.
  2. Defer mounting until height is known: `{h > 0 && <HtmlInCanvas height={h} ... />}`.
  3. Do not animate height through zero; toggle visibility instead.
  4. Verify the source of the value returns integers, not sub-pixel floats.

Example fix

// before
<HtmlInCanvas width={1920} height={state.loaded ? state.h : 0}>...</HtmlInCanvas>
// after
{state.loaded && <HtmlInCanvas width={1920} height={Math.max(1, Math.round(state.h))}>...</HtmlInCanvas>}
Defensive patterns

Strategy: validation

Validate before calling

if (!Number.isInteger(height) || height <= 0) {
  throw new RangeError(`height must be a positive integer; got ${height}`);
}

Type guard

const isPositiveInt = (n: unknown): n is number =>
  typeof n === 'number' && Number.isInteger(n) && n > 0;

Prevention

When it happens

Trigger: Passing `height={0}`, `height={-100}`, `height={1080.25}`, or `height={NaN}` to <HtmlInCanvas>; deriving height from a measurement that returns 0 initially.

Common situations: Responsive layouts where height collapses to 0 during transitions; floats from sub-pixel measurements; defaulting height to 0 before data loads.

Related errors


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