remotion-dev/remotion · error · TypeError
trimAfter prop must be greater than trimBefore prop.
Error message
trimAfter prop must be greater than trimBefore prop.
What it means
validateTrimProps enforces that trimAfter must be strictly greater than trimBefore, otherwise the requested playback window is empty or inverted. This check runs after individual type/range checks so both values are known to be valid numbers.
Source
Thrown at packages/core/src/validate-start-from-props.ts:87
if (typeof trimAfter !== 'number') {
throw new TypeError(
`type of trimAfter prop must be a number, instead got type ${typeof trimAfter}.`,
);
}
if (isNaN(trimAfter)) {
throw new TypeError('trimAfter prop can not be NaN.');
}
if (trimAfter <= 0) {
throw new TypeError(
`trimAfter must be a positive number, instead got ${trimAfter}.`,
);
}
}
if ((trimAfter as number) <= (trimBefore as number)) {
throw new TypeError('trimAfter prop must be greater than trimBefore prop.');
}
};
export const validateMediaTrimProps = ({
startFrom,
endAt,
trimBefore,
trimAfter,
}: {
startFrom: number | undefined;
endAt: number | undefined;
trimBefore: number | undefined;
trimAfter: number | undefined;
}) => {
// Check for conflicting props
if (typeof startFrom !== 'undefined' && typeof trimBefore !== 'undefined') {
throw new TypeError(
'Cannot use both startFrom and trimBefore props. Use trimBefore instead as startFrom is deprecated.',View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure trimAfter is strictly greater than trimBefore: trimBefore={50} trimAfter={200}.
- If computing dynamically, assert order before rendering: trimAfter = Math.max(trimAfter, trimBefore + 1).
- Swap the two values if they were reversed.
Example fix
// before
<Audio src={src} trimBefore={100} trimAfter={50} />
// after
<Audio src={src} trimBefore={50} trimAfter={100} /> Defensive patterns
Strategy: validation
Validate before calling
if (
trimBefore !== undefined &&
trimAfter !== undefined &&
trimAfter <= trimBefore
) {
throw new Error('trimAfter must be greater than trimBefore');
} Type guard
const isValidTrimWindow = ( trimBefore: unknown, trimAfter: unknown, ): boolean => typeof trimBefore === 'number' && typeof trimAfter === 'number' && Number.isFinite(trimBefore) && Number.isFinite(trimAfter) && trimAfter > trimBefore;
Prevention
- When computing both values dynamically, assert trimAfter > trimBefore before rendering.
- Derive trimAfter from trimBefore + duration to keep ordering invariant by construction.
- Double-check argument order when passing both props.
When it happens
Trigger: Passing both trimBefore and trimAfter where trimAfter <= trimBefore, e.g. trimBefore={100} trimAfter={50}, or computed values where the trim window inverts.
Common situations: Swapping trimBefore and trimAfter by mistake; computing both from a dynamic source where the ordering assumption breaks; off-by-one when the two values are derived from separate timestamps.
Related errors
- startFrom must be greater than equal to 0 instead got ${star
- endAt must be a positive number, instead got ${endAt}.
- endAt prop must be greater than startFrom prop.
- trimBefore must be greater than equal to 0 instead got ${tri
- trimAfter must be a positive number, instead got ${trimAfter
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/7eef1604e26504fb.
Report an issue: GitHub.