remotion-dev/remotion · error · Error
${path}.endMs must not be earlier than startMs.
Error message
${path}.endMs must not be earlier than startMs. What it means
parseCaptionFile enforces chronological caption timing: if a caption's endMs is earlier than its startMs, the file is rejected. This catches inverted or corrupt timing ranges in the loaded captions JSON and reports which indexed caption is at fault.
Source
Thrown at packages/studio/src/components/parse-caption-file.ts:55
const path = `captions[${index}]`;
if (!isObject(caption)) {
throw new Error(`${path} must be an object.`);
}
if (typeof caption.text !== 'string') {
throw new Error(`${path}.text must be a string.`);
}
if (!isFiniteNumber(caption.startMs) || caption.startMs < 0) {
throw new Error(`${path}.startMs must be a finite, non-negative number.`);
}
if (!isFiniteNumber(caption.endMs) || caption.endMs < 0) {
throw new Error(`${path}.endMs must be a finite, non-negative number.`);
}
if (caption.endMs < caption.startMs) {
throw new Error(`${path}.endMs must not be earlier than startMs.`);
}
if (caption.timestampMs !== null && !isFiniteNumber(caption.timestampMs)) {
throw new Error(`${path}.timestampMs must be a finite number or null.`);
}
if (caption.confidence !== null && !isFiniteNumber(caption.confidence)) {
throw new Error(`${path}.confidence must be a finite number or null.`);
}
if (
typeof caption.confidence === 'number' &&
(caption.confidence < 0 || caption.confidence > 1)
) {
throw new Error(`${path}.confidence must be between 0 and 1.`);
}
if (View on GitHub (pinned to b2f4e34732)
Solutions
- Swap or correct startMs/endMs so endMs >= startMs
- Re-sort/recompute timings in the exporting tool
- Convert all times to the same unit (milliseconds)
Example fix
// before
{"text": "hi", "startMs": 2000, "endMs": 1000}
// after
{"text": "hi", "startMs": 1000, "endMs": 2000} Defensive patterns
Strategy: validation
Validate before calling
for (const [i, c] of parsed.entries()) {
if ((c as any).endMs < (c as any).startMs) {
throw new Error(`captions[${i}]: endMs must be >= startMs`);
}
} Type guard
const hasValidRange = (c: {startMs: number; endMs: number}): boolean =>
c.endMs >= c.startMs; Try / catch
try {
const captions = parseCaptionFile({fileName, contents});
} catch (e) {
// fix the inverted range in the reported element and retry
} Prevention
- Clamp endMs = Math.max(endMs, startMs) in the export pipeline
- Avoid mixing units (seconds vs ms) across cues
- Check timings after any manual timestamp edits
When it happens
Trigger: captions[i] has endMs < startMs, e.g. {"startMs": 2000, "endMs": 1000}, commonly after sorting mistakes or ms/seconds unit mixing.
Common situations: Hand-editing timestamps and swapping values; one caption in seconds and the next in milliseconds; transcription drift producing inverted ranges.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Expected a Remotion Caption[] JSON array.
- ${path} must be an object.
- ${path}.text must be a string.
- ${path}.startMs must be a finite, non-negative number.
- ${path}.endMs must be a finite, non-negative number.
AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09).
Data as JSON: /api/errors/1bf8d07d1601965f.
Report an issue: GitHub.