remotion-dev/remotion · error · TypeError
The `toneFrequency` prop of <${component}> must be a finite
Error message
The `toneFrequency` prop of <${component}> must be a finite number between 0.01 and 2, but got ${String(toneFrequency)}. What it means
validateToneFrequency checks the toneFrequency prop used by pitch-shifting audio components (<OffthreadAudioWithPitch>, pitch helpers). It must be a finite number in [0.01, 2] — below 0.01 the shift is imperceptible/degenerate, above 2 the time-stretcher quality degrades. Anything else (NaN, Infinity, strings, out-of-range) throws this TypeError.
Source
Thrown at packages/media/src/validate-tone-frequency.ts:18
export const validateToneFrequency = ({
toneFrequency,
component,
}: {
toneFrequency: number | undefined;
component: 'Audio' | 'Video';
}) => {
if (toneFrequency === undefined) {
return;
}
if (
typeof toneFrequency !== 'number' ||
!Number.isFinite(toneFrequency) ||
toneFrequency < 0.01 ||
toneFrequency > 2
) {
throw new TypeError(
`The \`toneFrequency\` prop of <${component}> must be a finite number between 0.01 and 2, but got ${String(toneFrequency)}.`,
);
}
};
View on GitHub (pinned to a6a7485a9a)
Solutions
- Clamp/validate toneFrequency to [0.01, 2] before passing it
- Coerce string inputs with Number() and check Number.isFinite
- Fix the computation producing NaN/Infinity (guard divide-by-zero)
- If higher pitch is needed, chain processing or raise a feature request instead of exceeding 2
Example fix
// before
<OffthreadAudioWithPitch toneFrequency={Number(searchParams.get('pitch'))} .../>
// after
const raw = Number(searchParams.get('pitch'));
const toneFrequency = Math.min(2, Math.max(0.01, Number.isFinite(raw) ? raw : 1));
<OffthreadAudioWithPitch toneFrequency={toneFrequency} .../> Defensive patterns
Strategy: validation
Validate before calling
const toToneFrequency = (v: unknown): number => {
const n = Number(v);
if (!Number.isFinite(n) || n < 0.01 || n > 2) {
throw new TypeError(`toneFrequency must be a finite number in [0.01, 2], got ${String(v)}`);
}
return n;
}; Type guard
const isToneFrequency = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0.01 && v <= 2;
Try / catch
try {
validateToneFrequency({component: 'OffthreadAudioWithPitch', toneFrequency});
} catch (e) {
if (e instanceof TypeError && e.message.includes('toneFrequency')) {
toneFrequency = 1; // sensible default (no pitch shift)
} else throw e;
} Prevention
- Coerce and validate toneFrequency at the edge (props, query params, config)
- Clamp user-provided values into [0.01, 2] with Math.min/Math.max
- Guard computed values against NaN/Infinity before passing
- Default to 1 (no pitch change) when input is invalid
When it happens
Trigger: Passing toneFrequency as NaN/Infinity, a string (e.g. from an env var or URL param), 0, a negative number, or a value > 2 to a component/hook that validates it with validateToneFrequency.
Common situations: Parsing toneFrequency from JSON/query params without Number(); computing it with a formula that divides by zero; experimenting with extreme pitch values like 3x; passing undefined-adjacent values coerced by upstream code.
Related errors
- The "freeze" prop is not supported on <Html5Audio />. Use <S
- The `<Html5Audio>` tag requires a string for `src`, but got
- 'preservePitch' must be a boolean or undefined but got '${ty
- No 'src' was passed to <Html5Audio>.
- Emoji ${emoji} not found. Available emojis: ${emojis.map((e)
AI-assisted analysis of remotion-dev/remotion@a6a7485a9a (2026-09-02).
Data as JSON: /api/errors/13320bd2e43c508f.
Report an issue: GitHub.