remotion-dev/remotion · error · Error

${path}.endMs must be a finite, non-negative number.

Error message

${path}.endMs must be a finite, non-negative number.

What it means

parseCaptionFile requires each caption's endMs to be a finite, non-negative number (checked with isFiniteNumber). NaN, Infinity, negative values, or missing/non-numeric endMs fields in a captions JSON file trigger this error with the offending caption's index path.

Source

Thrown at packages/studio/src/components/parse-caption-file.ts:51

	}

	let previousStart: number | null = null;
	for (const [index, caption] of parsed.entries()) {
		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)
		) {

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Provide endMs as a finite number of milliseconds
  2. Replace null/-1/Infinity with an actual end time
  3. Convert seconds to milliseconds

Example fix

// before
{"text": "hi", "startMs": 0, "endMs": null}
// after
{"text": "hi", "startMs": 0, "endMs": 1200}
Defensive patterns

Strategy: validation

Validate before calling

for (const [i, c] of parsed.entries()) {
  const e = (c as any).endMs;
  if (typeof e !== 'number' || !Number.isFinite(e) || e < 0) {
    throw new Error(`captions[${i}].endMs must be a finite non-negative number`);
  }
}

Type guard

const isValidEndMs = (v: unknown): v is number =>
  typeof v === 'number' && Number.isFinite(v) && v >= 0;

Try / catch

try {
  const captions = parseCaptionFile({fileName, contents});
} catch (e) {
  // give open-ended cues a concrete endMs before retrying
}

Prevention

When it happens

Trigger: captions[i].endMs is absent, a string, NaN, Infinity, or < 0 when parseCaptionFile iterates the array.

Common situations: Open-ended cues exported with endMs: null or omitted (e.g. from SRT-like sources); times in seconds not ms; transcription tool emitting Infinity.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@b2f4e34732 (2026-09-09). Data as JSON: /api/errors/c75b06a3ec45db9c. Report an issue: GitHub.