remotion-dev/remotion · error · TypeError

"${name}" must be an integer, but got ${JSON.stringify(value

Error message

"${name}" must be an integer, but got ${JSON.stringify(value)}

What it means

Thrown by the venetian-blinds effect's validatePositiveInteger when the slats parameter (after resolving defaults) is not an integer. The check runs after resolve() applies the default of 12, so it only fires if the caller explicitly set slats to a non-integer like 12.5 or 12.0 (which is actually fine) — really it catches fractional values like 12.5, 3.14, or non-number values that passed the earlier assertOptionalFiniteNumber but fail Number.isInteger.

Source

Thrown at packages/effects/src/venetian-blinds.ts:100

		return;
	}

	if (!variants.includes(value as T)) {
		throw new TypeError(
			`"${name}" must be ${formatEnum(variants)}, but got ${JSON.stringify(value)}`,
		);
	}
};

const resolve = (p: VenetianBlindsParams): VenetianBlindsResolved => ({
	progress: p.progress ?? DEFAULT_PROGRESS,
	direction: p.direction ?? DEFAULT_DIRECTION,
	slats: p.slats ?? DEFAULT_SLATS,
});

const validatePositiveInteger = (value: number, name: string): void => {
	if (!Number.isInteger(value)) {
		throw new TypeError(
			`"${name}" must be an integer, but got ${JSON.stringify(value)}`,
		);
	}

	if (value < 1) {
		throw new TypeError(
			`"${name}" must be >= 1, but got ${JSON.stringify(value)}`,
		);
	}
};

const validateVenetianBlindsParams = (params: VenetianBlindsParams): void => {
	assertEffectParamsObject(params, 'Venetian blinds');
	assertOptionalFiniteNumber(params.progress, 'progress');
	assertOptionalFiniteNumber(params.slats, 'slats');
	assertOptionalEnum(params.direction, 'direction', VENETIAN_BLINDS_DIRECTIONS);

	const r = resolve(params);

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass an integer: venetianBlinds({slats: 12})
  2. Round computed values: venetianBlinds({slats: Math.round(computed)})
  3. Use Math.floor or Math.ceil if rounding direction matters for the visual
  4. Check the schema: slats has min 1, max 100, step 1 — only integers in that range are valid

Example fix

// before
const e = venetianBlinds({slats: width / 64});

// after
const e = venetianBlinds({slats: Math.max(1, Math.round(width / 64))});
Defensive patterns

Strategy: validation

Validate before calling

function isPositiveInteger(value: unknown): boolean {
  return typeof value === 'number' && Number.isInteger(value) && value >= 1;
}

// Before calling:
if (!isPositiveInteger(params.slats)) {
  throw new Error('slats must be a positive integer');
}
const e = venetianBlinds(params);

Type guard

function isPositiveInteger(value: unknown): value is number {
  return typeof value === 'number' && Number.isInteger(value) && value >= 1;
}

Prevention

When it happens

Trigger: Calling venetianBlinds({slats: 12.5}) — 12.5 is a finite number so it passes assertOptionalFiniteNumber, but Number.isInteger(12.5) is false, triggering this error.

Common situations: Computed slat count from a formula that produces a float (e.g. width / pixelSize); data from a slider with fractional step; user input parsed as float.

Related errors


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