remotion-dev/remotion · error · Error
HtmlInCanvas: `width` must be a positive integer. Received:
Error message
HtmlInCanvas: `width` must be a positive integer. Received: ${String(width)}. What it means
Thrown by assertHtmlInCanvasDimensions after the type check passes, when `width` is a number but not a positive integer (zero, negative, fractional, NaN). The canvas allocation is `Math.ceil(width * pixelDensity)`, but fractional or non-positive widths produce degenerate or zero-area paint targets, so Remotion rejects them up front.
Source
Thrown at packages/core/src/HtmlInCanvas.tsx:257
) => void | Promise<void>;
export type HtmlInCanvasOnInitCleanup = () => void;
export type HtmlInCanvasOnInit = (
params: HtmlInCanvasOnPaintParams,
) => 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;
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Use `Math.max(1, Math.round(value))` when computing width from dynamic data.
- Guard mounting <HtmlInCanvas> until dimensions are known: `{w > 0 && <HtmlInCanvas width={w} ... />}`.
- Avoid animating width to/from zero; instead conditionally mount/unmount the component.
- Confirm constants and literals are positive integers, not expressions that evaluate to fractions.
Example fix
// before
<HtmlInCanvas width={props.scale * 1.5} height={1080}>...</HtmlInCanvas>
// after
<HtmlInCanvas width={Math.max(1, Math.round(props.scale * 1.5))} height={1080}>...</HtmlInCanvas> Defensive patterns
Strategy: validation
Validate before calling
if (!Number.isInteger(width) || width <= 0) {
throw new RangeError(`width must be a positive integer; got ${width}`);
} Type guard
const isPositiveInt = (n: unknown): n is number => typeof n === 'number' && Number.isInteger(n) && n > 0;
Prevention
- Round dynamic widths with `Math.max(1, Math.round(value))`.
- Defer mounting until a real measurement is available.
- Avoid animating width through zero.
- Add eslint no-magic-numbers or a wrapper assert in test builds.
When it happens
Trigger: Passing `width={0}`, `width={-10}`, `width={1920.5}`, or `width={NaN}` to <HtmlInCanvas>; computing width from a division that yields a fraction.
Common situations: Animating dimensions and letting them cross zero; using floats from layout calculations without rounding; defaulting width to 0 before a measurement arrives.
Related errors
- HtmlInCanvas: `height` must be a positive integer. Received:
- HtmlInCanvas: `pixelDensity` must be a positive finite numbe
- inputRange must contain only finite numbers, but got [${arr.
- Scale must be greater than 0
- HtmlInCanvas: `width` and `height` must be numbers. Received
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/fa89e81e7465a744.
Report an issue: GitHub.