{"record":{"id":"6cefb76b023255c6","repo":"remotion-dev/remotion","slug":"path-timestampms-must-be-a-finite-number-or-nul","errorCode":null,"errorMessage":"${path}.timestampMs must be a finite number or null.","messagePattern":"(.+?)\\.timestampMs must be a finite number or null\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/parse-caption-file.ts","lineNumber":59,"sourceCode":"\n\t\tif (typeof caption.text !== 'string') {\n\t\t\tthrow new Error(`${path}.text must be a string.`);\n\t\t}\n\n\t\tif (!isFiniteNumber(caption.startMs) || caption.startMs < 0) {\n\t\t\tthrow new Error(`${path}.startMs must be a finite, non-negative number.`);\n\t\t}\n\n\t\tif (!isFiniteNumber(caption.endMs) || caption.endMs < 0) {\n\t\t\tthrow new Error(`${path}.endMs must be a finite, non-negative number.`);\n\t\t}\n\n\t\tif (caption.endMs < caption.startMs) {\n\t\t\tthrow new Error(`${path}.endMs must not be earlier than startMs.`);\n\t\t}\n\n\t\tif (caption.timestampMs !== null && !isFiniteNumber(caption.timestampMs)) {\n\t\t\tthrow new Error(`${path}.timestampMs must be a finite number or null.`);\n\t\t}\n\n\t\tif (caption.confidence !== null && !isFiniteNumber(caption.confidence)) {\n\t\t\tthrow new Error(`${path}.confidence must be a finite number or null.`);\n\t\t}\n\n\t\tif (\n\t\t\ttypeof caption.confidence === 'number' &&\n\t\t\t(caption.confidence < 0 || caption.confidence > 1)\n\t\t) {\n\t\t\tthrow new Error(`${path}.confidence must be between 0 and 1.`);\n\t\t}\n\n\t\tif (\n\t\t\tcaption.pageBreakAfter !== undefined &&\n\t\t\ttypeof caption.pageBreakAfter !== 'boolean'\n\t\t) {\n\t\t\tthrow new Error(","sourceCodeStart":41,"sourceCodeEnd":77,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/studio/src/components/parse-caption-file.ts#L41-L77","documentation":"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.","triggerScenarios":"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.","commonSituations":"Timestamps serialized as ISO date strings by another tool; NaN sneaking in via JS computation before JSON.stringify; hand-editing mistakes.","solutions":["Set timestampMs to a finite number of milliseconds","Set it to null explicitly if not needed (or omit it if the schema allows)","Convert string timestamps to numbers"],"exampleFix":"// before\n{\"text\": \"hi\", \"startMs\": 0, \"endMs\": 1000, \"timestampMs\": \"2024-01-01T00:00:00Z\"}\n// after\n{\"text\": \"hi\", \"startMs\": 0, \"endMs\": 1000, \"timestampMs\": null}","handlingStrategy":"type-guard","validationCode":"for (const [i, c] of parsed.entries()) {\n  const t = (c as any).timestampMs;\n  if (t !== null && t !== undefined && (typeof t !== 'number' || !Number.isFinite(t))) {\n    throw new Error(`captions[${i}].timestampMs must be a finite number or null`);\n  }\n}","typeGuard":"const isValidTimestampMs = (v: unknown): v is number | null | undefined =>\n  v === null || v === undefined || (typeof v === 'number' && Number.isFinite(v));","tryCatchPattern":"try {\n  const captions = parseCaptionFile({fileName, contents});\n} catch (e) {\n  // normalize timestampMs to null or a number, then retry\n}","preventionTips":["Omit timestampMs or set it to null, never an ISO date string","Guard against NaN before JSON.stringify","Keep timestamps numeric throughout the pipeline"],"tags":["json","validation","captions"],"backgroundTag":"type-mismatch","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}