remotion-dev/remotion · error · TypeError
endAt prop must be greater than startFrom prop.
Error message
endAt prop must be greater than startFrom prop.
What it means
validateStartFromProps enforces that endAt must be greater than startFrom, 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:42
if (typeof endAt !== 'number') {
throw new TypeError(
`type of endAt prop must be a number, instead got type ${typeof endAt}.`,
);
}
if (isNaN(endAt)) {
throw new TypeError('endAt prop can not be NaN.');
}
if (endAt <= 0) {
throw new TypeError(
`endAt must be a positive number, instead got ${endAt}.`,
);
}
}
if ((endAt as number) < (startFrom as number)) {
throw new TypeError('endAt prop must be greater than startFrom prop.');
}
};
export const validateTrimProps = (
trimBefore: number | undefined,
trimAfter: number | undefined,
) => {
if (typeof trimBefore !== 'undefined') {
if (typeof trimBefore !== 'number') {
throw new TypeError(
`type of trimBefore prop must be a number, instead got type ${typeof trimBefore}.`,
);
}
if (isNaN(trimBefore) || trimBefore === Infinity) {
throw new TypeError('trimBefore prop can not be NaN or Infinity.');
}
View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Ensure endAt is strictly greater than startFrom: startFrom={50} endAt={200}.
- If computing dynamically, assert order before rendering: endAt = Math.max(endAt, startFrom + 1).
- Swap the two values if they were reversed.
- Migrate to trimBefore/trimAfter (same ordering constraint applies: trimAfter must exceed trimBefore).
Example fix
// before
<Audio src={src} startFrom={100} endAt={50} />
// after
<Audio src={src} trimBefore={50} trimAfter={100} /> Defensive patterns
Strategy: validation
Validate before calling
if (
startFrom !== undefined &&
endAt !== undefined &&
endAt <= startFrom
) {
throw new Error('endAt must be greater than startFrom');
} Type guard
const isValidWindow = ( startFrom: unknown, endAt: unknown, ): boolean => typeof startFrom === 'number' && typeof endAt === 'number' && Number.isFinite(startFrom) && Number.isFinite(endAt) && endAt > startFrom;
Prevention
- When computing both values dynamically, assert endAt > startFrom before rendering.
- Derive endAt from startFrom + duration to keep ordering invariant by construction.
- Prefer trimBefore/trimAfter over the deprecated pair.
When it happens
Trigger: Passing both startFrom and endAt where endAt <= startFrom, e.g. startFrom={100} endAt={50}, or computed values where the trim window inverts.
Common situations: Swapping startFrom and endAt by mistake; computing both from a dynamic source where the ordering assumption breaks; off-by-one when startFrom and endAt 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}.
- type of startFrom prop must be a number, instead got type ${
- startFrom prop can not be NaN or Infinity.
- type of endAt prop must be a number, instead got type ${type
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/9cbd95475a72ba27.
Report an issue: GitHub.