{"record":{"id":"f0c797e7cb1fe1b4","repo":"remotion-dev/remotion","slug":"path-startms-must-be-a-finite-non-negative-num","errorCode":null,"errorMessage":"${path}.startMs must be a finite, non-negative number.","messagePattern":"(.+?)\\.startMs must be a finite, non-negative number\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/studio/src/components/parse-caption-file.ts","lineNumber":47,"sourceCode":"\t}\n\n\tif (!Array.isArray(parsed)) {\n\t\tthrow new Error('Expected a Remotion Caption[] JSON array.');\n\t}\n\n\tlet previousStart: number | null = null;\n\tfor (const [index, caption] of parsed.entries()) {\n\t\tconst path = `captions[${index}]`;\n\t\tif (!isObject(caption)) {\n\t\t\tthrow new Error(`${path} must be an object.`);\n\t\t}\n\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","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/studio/src/components/parse-caption-file.ts#L29-L65","documentation":"parseCaptionFile requires each caption's startMs to be a finite, non-negative number (checked with isFiniteNumber). NaN, Infinity, negative values, or missing/non-numeric startMs fields in a captions JSON file trigger this error, reported with the index path of the offending caption.","triggerScenarios":"captions[i].startMs is absent, a string like \"1.5\", NaN, Infinity, or < 0 — detected by !isFiniteNumber(caption.startMs) || caption.startMs < 0.","commonSituations":"Times exported in seconds or \"00:00:01,500\" string format instead of milliseconds; timestamp of -1 from a buggy transcriber; missing field from a hand-written file.","solutions":["Convert times to milliseconds as numbers: 1.5s -> 1500","Set startMs to a non-negative finite number","Fix the negative value from the transcription source"],"exampleFix":"// before\n{\"text\": \"hi\", \"startMs\": \"00:00:01.500\", \"endMs\": 2000}\n// after\n{\"text\": \"hi\", \"startMs\": 1500, \"endMs\": 2000}","handlingStrategy":"validation","validationCode":"for (const [i, c] of parsed.entries()) {\n  const s = (c as any).startMs;\n  if (typeof s !== 'number' || !Number.isFinite(s) || s < 0) {\n    throw new Error(`captions[${i}].startMs must be a finite non-negative number`);\n  }\n}","typeGuard":"const isValidStartMs = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0;","tryCatchPattern":"try {\n  const captions = parseCaptionFile({fileName, contents});\n} catch (e) {\n  // convert seconds/timestamps to ms and retry\n}","preventionTips":["Always store caption times in milliseconds as JSON numbers","Reject/convert string timestamps during export","Sanity-check transcriber output for negative or NaN times"],"tags":["json","validation","captions"],"backgroundTag":"invalid-argument-value","analyzedSha":"b2f4e34732f3c6c222ea029413e22dc402218cd7","analyzedAt":"2026-09-09T13:27:51.281Z","contentChangedAt":"2026-09-09T13:27:51.281Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}