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
- Pass an integer: venetianBlinds({slats: 12})
- Round computed values: venetianBlinds({slats: Math.round(computed)})
- Use Math.floor or Math.ceil if rounding direction matters for the visual
- 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
- Round computed slat counts with Math.round before passing: Math.round(computed)
- Check Number.isInteger on user-provided values before passing to the effect
- Use the Studio schema (slats: step 1, min 1, max 100) as a guide for valid integer ranges
- Avoid passing float results of division formulas directly
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
- "${name}" must be ${formatEnum(variants)}, but got ${JSON.st
- "${name}" must be >= 1, but got ${JSON.stringify(value)}
- "invert" must be a boolean, but got ${JSON.stringify(params.
- "${name}" must be a [number, number] tuple
- "${name}" must be an integer, but got ${JSON.stringify(value
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/829083376496aad3.
Report an issue: GitHub.