remotion-dev/remotion · error · TypeError

"${name}" must be greater than 0, but got ${JSON.stringify(v

Error message

"${name}" must be greater than 0, but got ${JSON.stringify(value)}

What it means

Thrown by validatePositive() in the lines effect when `thickness` (after applying the default) is <= 0. Line thickness must be strictly positive because it determines the fragment shader's stroke width, so zero/negative values are rejected at setup. Note `gap` uses the separate validateNonNegative and allows 0.

Source

Thrown at packages/effects/src/lines.ts:166

		offset: p.offset ?? DEFAULT_OFFSET,
		maskToSourceAlpha: p.maskToSourceAlpha ?? DEFAULT_MASK_TO_SOURCE_ALPHA,
	};
};

const formatEnum = (variants: readonly string[]): string => {
	if (variants.length === 2) {
		return `"${variants[0]}" or "${variants[1]}"`;
	}

	return `${variants
		.slice(0, -1)
		.map((variant) => `"${variant}"`)
		.join(', ')} or "${variants[variants.length - 1]}"`;
};

const validatePositive = (value: number, name: string): void => {
	if (value <= 0) {
		throw new TypeError(
			`"${name}" must be greater than 0, but got ${JSON.stringify(value)}`,
		);
	}
};

const validateNonNegative = (value: number, name: string): void => {
	if (value < 0) {
		throw new TypeError(
			`"${name}" must be greater than or equal to 0, but got ${JSON.stringify(value)}`,
		);
	}
};

const validateColors = (colors: unknown): void => {
	if (colors === undefined) {
		return;
	}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Set `thickness` to a positive number (e.g. >= 1); use the default by omitting the field.
  2. When animating, clamp: Math.max(Number.EPSILON, interpolate({ input, range, output })) or conditionally unmount the effect when it should be invisible.
  3. To hide the lines, remove the effect from the sequence rather than setting thickness to 0.
  4. Double-check interpolate's `extrapolateLeft/Right` so the output never reaches 0.

Example fix

// before
lines({ colors: ['#000', '#fff'], thickness: interpolate({ input: frame, range: [0, 30], output: [0, 10] }) });

// after — clamp to a tiny positive value, or unmount when it should be hidden
const thickness = Math.max(0.001, interpolate({ input: frame, range: [0, 30], output: [0.001, 10], extrapolateLeft: 'clamp', extrapolateRight: 'clamp' }));
lines({ colors: ['#000', '#fff'], thickness });
Defensive patterns

Strategy: validation

Validate before calling

import {interpolate} from 'remotion';

// Thickness must stay strictly positive; clamp at a tiny epsilon or unmount to hide.
const safeThickness = (v: number) => Math.max(0.001, v);

const thickness = safeThickness(
  interpolate({input: frame, range: [0, 30], output: [0.001, 10], extrapolateLeft: 'clamp', extrapolateRight: 'clamp'})
);
lines({colors: ['#000', '#fff'], thickness});

Type guard

const isValidThickness = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v) && v > 0;

Prevention

When it happens

Trigger: Calling lines({ thickness: 0 }) or with a negative thickness, or animating thickness and letting it reach/cross 0. Because the default is substituted before validation, passing `undefined` is safe — only an explicit <=0 number triggers it.

Common situations: Animators driving thickness to 0 to 'hide' the lines instead of unmounting the effect; copy-pasting a value from a different effect whose minimum is 0; off-by-one in interpolate output arrays; passing a value computed from a division that can yield 0.

Related errors


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