remotion-dev/remotion · error · Error
The waveform sample rate must be a positive number.
Error message
The waveform sample rate must be a positive number.
What it means
loadWaveformPeaks resamples audio into a Float32Array of peaks at a caller-supplied sample rate (options.waveformSampleRate, defaulting to TARGET_SAMPLE_RATE). It validates the rate up front and throws if it is not a finite number greater than zero, because a zero/negative/NaN rate would make resampling math and the cache key nonsensical. The cache is keyed per sample rate, so the value must be a well-defined positive number.
Source
Thrown at packages/timeline-utils/src/audio-waveform/load-waveform-peaks.ts:42
readonly completedPeaks: number;
readonly totalPeaks: number;
readonly final: boolean;
};
type LoadWaveformPeaksOptions = {
readonly onProgress?: (progress: Progress) => void;
readonly progressIntervalInMs?: number;
readonly waveformSampleRate?: number;
};
export async function loadWaveformPeaks(
src: string | InputAudioTrack,
signal: AbortSignal,
options?: LoadWaveformPeaksOptions,
): Promise<WaveformResult> {
const waveformSampleRate = options?.waveformSampleRate ?? TARGET_SAMPLE_RATE;
if (!Number.isFinite(waveformSampleRate) || waveformSampleRate <= 0) {
throw new Error('The waveform sample rate must be a positive number.');
}
const cacheKey = getWaveformCacheKey(src, waveformSampleRate);
const cached = peaksCache.get(cacheKey);
if (cached) {
emitWaveformProgress({
peaks: cached.peaks,
averageVolume: cached.averageVolume,
completedPeaks: cached.peaks.length,
totalPeaks: cached.peaks.length,
final: true,
onProgress: options?.onProgress,
});
return cached;
}
const input =
typeof src === 'string'View on GitHub (pinned to b2f4e34732)
Solutions
- Pass a positive finite number, e.g. { waveformSampleRate: 100 }
- Omit waveformSampleRate entirely to use the built-in default (TARGET_SAMPLE_RATE)
- Coerce safely: const rate = Number(cfg.rate); if (!Number.isFinite(rate) || rate <= 0) rate = 100;
- Check where the value originates (config file, prop, division) and fix the source producing 0/NaN
Example fix
// before
loadWaveformPeaks(url, signal, { waveformSampleRate: cfg.sampleRate ?? 0 })
// after
loadWaveformPeaks(url, signal, cfg.sampleRate && Number.isFinite(cfg.sampleRate) && cfg.sampleRate > 0 ? { waveformSampleRate: cfg.sampleRate } : undefined) Defensive patterns
Strategy: validation
Validate before calling
function isValidSampleRate(rate: unknown): rate is number {
return typeof rate === 'number' && Number.isFinite(rate) && rate > 0;
}
const options = isValidSampleRate(cfg.waveformSampleRate) ? { waveformSampleRate: cfg.waveformSampleRate } : undefined; Type guard
function isValidSampleRate(rate: unknown): rate is number {
return typeof rate === 'number' && Number.isFinite(rate) && rate > 0;
} Try / catch
try {
const peaks = await loadWaveformPeaks(url, signal, options);
} catch (err) {
if (err instanceof Error && err.message.includes('waveform sample rate must be a positive number')) {
return loadWaveformPeaks(url, signal); // fall back to default TARGET_SAMPLE_RATE
}
throw err;
} Prevention
- Only pass waveformSampleRate when it is a validated positive finite number
- Coerce config values with Number() and guard Number.isFinite before use
- Rely on the library default (omit the option) unless you specifically need custom resampling
- Add a schema check (zod/valibot) for waveformSampleRate: z.number().positive().finite()
When it happens
Trigger: Passing LoadWaveformPeaksOptions.waveformSampleRate as 0, a negative number, NaN, Infinity, or a string/undefined-derived value (e.g. Number(undefined)) from the caller; startMainThreadLoad / peaks / defaultPeaks / detailedPeaks funnel the same bad value in.
Common situations: Computing the sample rate from config that failed to load (undefined -> NaN via arithmetic); a JSON config where the field is 0 or missing and a default of 0 is used; unit mismatches (milliseconds vs Hz) yielding tiny or negative values.
Related errors
- No src passed
- The "freeze" prop is not supported on <Html5Audio />. Use <S
- The `<Html5Audio>` tag requires a string for `src`, but got
- Changing the AudioContext sample rate dynamically is not sup
- You have passed a volume of type ${typeof props.volume} to y
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/3e7cbc0c856d3523.
Report an issue: GitHub.