remotion-dev/remotion · error · TypeError
A numeric bitrate must be a positive integer.
Error message
A numeric bitrate must be a positive integer.
What it means
resolveVideoMattingQuality converts a VideoMattingBitrate into a Quality. When the caller passes a number, it must be a positive integer bitrate in bits per second; non-integers, zero, negative values, NaN or Infinity are rejected with a TypeError. This ensures the underlying encoder receives a valid bitrate.
Source
Thrown at packages/video-matting/src/video-matting-quality.ts:20
export const VIDEO_MATTING_QUALITIES = [
'very-low',
'low',
'medium',
'high',
'very-high',
] as const;
export type VideoMattingQuality = (typeof VIDEO_MATTING_QUALITIES)[number];
export type VideoMattingBitrate = number | VideoMattingQuality;
export const resolveVideoMattingQuality = (
value: VideoMattingBitrate,
): Quality => {
if (typeof value === 'number') {
if (!Number.isInteger(value) || value <= 0) {
throw new TypeError('A numeric bitrate must be a positive integer.');
}
return new Quality({bitrate: value});
}
if (!VIDEO_MATTING_QUALITIES.includes(value)) {
throw new TypeError(
`The bitrate quality must be one of ${VIDEO_MATTING_QUALITIES.join(', ')}.`,
);
}
return new Quality({quality: value, preferBitrate: true});
};
View on GitHub (pinned to b2f4e34732)
Solutions
- Pass a positive integer, e.g. 4_000_000 instead of 4e6/3 or 0
- Round and validate dynamic bitrates: Math.round(computed) and check > 0 before calling
- Use a named quality preset ('low' | 'medium' | 'high') instead of a raw number if unsure
- Fix config parsing so unset/0 values fall back to a default rather than being passed as bitrate
Example fix
// before
const q = resolveVideoMattingQuality(bitrateFromConfig); // 0 or 3.5
// after
const bitrate = Math.round(Number(bitrateFromConfig));
if (!Number.isInteger(bitrate) || bitrate <= 0) throw new Error('Invalid bitrate in config');
const q = resolveVideoMattingQuality(bitrate); Defensive patterns
Strategy: validation
Validate before calling
const isValidBitrate = (v: unknown): v is number =>
typeof v === 'number' && Number.isInteger(v) && v > 0;
if (!isValidBitrate(bitrate)) throw new TypeError(`Invalid bitrate: ${bitrate}`); Type guard
const isNumericBitrate = (v: VideoMattingBitrate): v is number => typeof v === 'number'; const isValidNumericBitrate = (v: VideoMattingBitrate): v is number => typeof v === 'number' && Number.isInteger(v) && v > 0;
Try / catch
try {
const quality = resolveVideoMattingQuality(bitrate);
} catch (err) {
if (err instanceof TypeError && err.message.includes('positive integer')) {
return resolveVideoMattingQuality(4_000_000); // sensible default
}
throw err;
} Prevention
- Round computed bitrates with Math.round before passing
- Treat 0/undefined config values as 'use default', never as bitrate
- Use parseInt (not parseFloat) when parsing bitrate strings
- Centralize bitrate validation in one config-parsing step
When it happens
Trigger: Passing a number bitrate like 0, -5000, 3.5, NaN or Infinity to resolveVideoMattingQuality — typically via a videoMatting quality/bitrate option in the render or component API.
Common situations: Computing a bitrate dynamically (e.g. width * height * factor) producing a float, a config value of 0 meaning 'unset' being passed through, or parsing a user-supplied string with parseFloat instead of parseInt.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- videoBitrate is invalid.
- The bitrate quality must be one of ${VIDEO_MATTING_QUALITIES
- Video timestamps must be finite numbers.
- The video frame timestamp must be finite.
- The video frame duration must be non-negative.
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/1d3ebd75bfbec5e9.
Report an issue: GitHub.