remotion-dev/remotion · error · TypeError
keyframeIntervalInSeconds must be a positive finite number.
Error message
keyframeIntervalInSeconds must be a positive finite number.
What it means
validateOptions for separateVideoLayers() accepts an optional keyframeIntervalInSeconds for the output container; it must be a positive finite number. Non-finite values, zero, or negatives are rejected after bitrate options (which go through resolveVideoMattingQuality) are validated.
Source
Thrown at packages/video-matting/src/separate-video-layers.ts:216
if (
options.audio !== undefined &&
!AUDIO_DESTINATIONS.includes(options.audio)
) {
throw new TypeError(
'audio must be one of base, foreground, both, or none.',
);
}
resolveVideoMattingQuality(options.videoBitrate ?? 'very-high');
resolveVideoMattingQuality(options.audioBitrate ?? 'medium');
if (
options.keyframeIntervalInSeconds !== undefined &&
(!Number.isFinite(options.keyframeIntervalInSeconds) ||
options.keyframeIntervalInSeconds <= 0)
) {
throw new TypeError(
'keyframeIntervalInSeconds must be a positive finite number.',
);
}
if (
options.onProgress !== undefined &&
typeof options.onProgress !== 'function'
) {
throw new TypeError('onProgress must be a function.');
}
if (
options.onModelLoadProgress !== undefined &&
typeof options.onModelLoadProgress !== 'function'
) {
throw new TypeError('onModelLoadProgress must be a function.');
}
};View on GitHub (pinned to b2f4e34732)
Solutions
- Pass a positive finite number, e.g. keyframeIntervalInSeconds: 2
- Omit the option to use the library default
- Guard parsed values with Number.isFinite(v) && v > 0 before calling
Example fix
// before
const kf = Number(process.env.KF_SECONDS); // '' -> 0
await separateVideoLayers({ src, outputs, keyframeIntervalInSeconds: kf });
// after
const kf = Number(process.env.KF_SECONDS);
const opts = { src, outputs };
if (kf > 0 && Number.isFinite(kf)) opts.keyframeIntervalInSeconds = kf;
await separateVideoLayers(opts); Defensive patterns
Strategy: validation
Validate before calling
if (kf !== undefined && (!Number.isFinite(kf) || kf <= 0)) throw new TypeError('keyframeIntervalInSeconds must be a positive finite number'); Type guard
const isPositiveFinite = (v) => typeof v === 'number' && Number.isFinite(v) && v > 0;
Try / catch
try { await separateVideoLayers(opts); } catch (e) { if (e instanceof TypeError && e.message.includes('keyframeIntervalInSeconds')) { /* fix or drop the value */ } else throw e; } Prevention
- Use Number.isFinite checks after any Number()/parseFloat
- Don't use 0 to mean 'auto' — omit the option instead
- Avoid computing intervals with divisions that can yield 0/Infinity
When it happens
Trigger: Passing keyframeIntervalInSeconds: 0 (thinking 0 = auto), -1, NaN from a failed parseFloat, or Infinity from a division by zero.
Common situations: Parsing CLI flags with Number() and not checking NaN; computing the interval from fps math that divided by zero; config defaulting to 0.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Emoji ${emoji} not found. Available emojis: ${emojis.map((e)
- The start and end values must be of the same type. Start val
- Non-animatable values cannot be interpolated. Start value: $
- The units of the start and end values must match. Start valu
- The start and end values must have the same structure. Start
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/f885b32bfc68b840.
Report an issue: GitHub.