remotion-dev/remotion · error · TypeError
You passed in a a function to the volume prop but it did not
Error message
You passed in a a function to the volume prop but it did not return a number but a value of type ${typeof evaluated} for frame ${frame} What it means
TypeError thrown by `evaluateVolume` when the `volume` prop is a function but calling `volume(frame)` produced a value whose type is not 'number' (after multiplying by mediaVolume). Remotion's VolumeProp accepts either a number or a function (frame) => number; if the function returns a string, object, undefined, etc., this error fires. Note the original message contains a duplicated 'a a' typo. The evaluated value's typeof is included along with the frame number.
Source
Thrown at packages/core/src/volume-prop.ts:22
frame,
volume,
mediaVolume = 1,
}: {
frame: number;
volume: VolumeProp | undefined;
mediaVolume: number;
}): number => {
if (typeof volume === 'number') {
return volume * mediaVolume;
}
if (typeof volume === 'undefined') {
return Number(mediaVolume);
}
const evaluated = volume(frame) * mediaVolume;
if (typeof evaluated !== 'number') {
throw new TypeError(
`You passed in a a function to the volume prop but it did not return a number but a value of type ${typeof evaluated} for frame ${frame}`,
);
}
if (Number.isNaN(evaluated)) {
throw new TypeError(
`You passed in a function to the volume prop but it returned NaN for frame ${frame}.`,
);
}
if (!Number.isFinite(evaluated)) {
throw new TypeError(
`You passed in a function to the volume prop but it returned a non-finite number for frame ${frame}.`,
);
}
return Math.max(0, evaluated);
};View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure the volume callback always returns a number for every frame: add explicit `return 0;` in fallback branches.
- Annotate the callback as `(frame: number): number => ...` so TypeScript catches non-number returns at compile time.
- Unit-test the callback across all frames in the composition duration to find the offending frame noted in the message.
Example fix
// before
<Video src={s} volume={(f) => {
if (f > 30) return 0.5;
// missing return -> undefined
}} />
// after
<Video src={s} volume={(f: number): number => {
if (f > 30) return 0.5;
return 0;
}} /> Defensive patterns
Strategy: validation
Validate before calling
import type {VolumeProp} from 'remotion';
const validateVolumeFn = (v: VolumeProp, frames: number[]) => {
if (typeof v !== 'function') return;
for (const f of frames) {
const out = v(f);
if (typeof out !== 'number')
throw new Error(`volume() returned ${typeof out} at frame ${f}`);
}
}; Type guard
const isVolumeFn = (v: unknown): v is ((frame: number) => number) => typeof v === 'function';
Prevention
- Annotate volume callbacks as `(frame: number): number => ...`.
- Ensure every branch returns a number; add a final `return 0;`.
- Test the callback over the full frame range before rendering.
When it happens
Trigger: Passing `volume={(frame) => someString}` or any volume callback whose return is not a number for at least one frame in the composition's range. For example returning `undefined` from a branch, a string like '0.5', or forgetting to return from the callback.
Common situations: A volume callback with a missing `return` in one branch; returning a value from a map/lookup that is occasionally undefined; migrating from a number volume to a function and leaving a non-number return type.
Related errors
- The `<Html5Audio>` tag requires a string for `src`, but got
- You have passed a volume of type ${typeof props.volume} to y
- You have passed a volume below 0 to your <${component} /> co
- You passed in a function to the volume prop but it returned
- You passed in a function to the volume prop but it returned
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/0fff1bdce4600f9d.
Report an issue: GitHub.