remotion-dev/remotion · error · Error

${path}.timestampMs must be a finite number or null.

Error message

${path}.timestampMs must be a finite number or null.

What it means

parseCaptionFile allows the optional timestampMs field to be either null or a finite number; anything else (undefined handling aside, NaN/Infinity, strings, objects) is rejected. Fires while validating an indexed caption in the loaded captions JSON.

Source

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

		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 (
			caption.pageBreakAfter !== undefined &&
			typeof caption.pageBreakAfter !== 'boolean'
		) {
			throw new Error(

View on GitHub (pinned to b2f4e34732)

Solutions

  1. Set timestampMs to a finite number of milliseconds
  2. Set it to null explicitly if not needed (or omit it if the schema allows)
  3. Convert string timestamps to numbers

Example fix

// before
{"text": "hi", "startMs": 0, "endMs": 1000, "timestampMs": "2024-01-01T00:00:00Z"}
// after
{"text": "hi", "startMs": 0, "endMs": 1000, "timestampMs": null}
Defensive patterns

Strategy: type-guard

Validate before calling

for (const [i, c] of parsed.entries()) {
  const t = (c as any).timestampMs;
  if (t !== null && t !== undefined && (typeof t !== 'number' || !Number.isFinite(t))) {
    throw new Error(`captions[${i}].timestampMs must be a finite number or null`);
  }
}

Type guard

const isValidTimestampMs = (v: unknown): v is number | null | undefined =>
  v === null || v === undefined || (typeof v === 'number' && Number.isFinite(v));

Try / catch

try {
  const captions = parseCaptionFile({fileName, contents});
} catch (e) {
  // normalize timestampMs to null or a number, then retry
}

Prevention

When it happens

Trigger: captions[i].timestampMs is e.g. "12.5" (string), NaN, or Infinity; the check passes only if it is exactly null or a finite number.

Common situations: Timestamps serialized as ISO date strings by another tool; NaN sneaking in via JS computation before JSON.stringify; hand-editing mistakes.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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