{"record":{"id":"72e79e8e608331ae","repo":"remotion-dev/remotion","slug":"videoendtimestamp-must-be-a-finite-number","errorCode":null,"errorMessage":"videoEndTimestamp must be a finite number.","messagePattern":"videoEndTimestamp must be a finite number\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/video-matting/src/prepare-audio.ts","lineNumber":64,"sourceCode":"\tvideoEndTimestamp,\n\taudioQuality,\n\tforceTranscode,\n}: {\n\tinput: Input;\n\tbaseOutput: Output<WebMOutputFormat, BaseTarget>;\n\tforegroundOutput: Output<WebMOutputFormat, ForegroundTarget>;\n\tdestination: VideoMattingAudioDestination;\n\tvideoStartTimestamp: number;\n\tvideoEndTimestamp: number;\n\taudioQuality: Quality | null;\n\tforceTranscode: boolean;\n}): Promise<PreparedVideoMattingAudio> => {\n\tif (!Number.isFinite(videoStartTimestamp)) {\n\t\tthrow new TypeError('videoStartTimestamp must be a finite number.');\n\t}\n\n\tif (!Number.isFinite(videoEndTimestamp)) {\n\t\tthrow new TypeError('videoEndTimestamp must be a finite number.');\n\t}\n\n\tif (videoEndTimestamp < videoStartTimestamp) {\n\t\tthrow new RangeError(\n\t\t\t'videoEndTimestamp must be greater than or equal to videoStartTimestamp.',\n\t\t);\n\t}\n\n\tif (typeof forceTranscode !== 'boolean') {\n\t\tthrow new TypeError('forceTranscode must be a boolean.');\n\t}\n\n\tif (destination === 'none') {\n\t\treturn {\n\t\t\tprime: () => Promise.resolve(),\n\t\t\twriteAudioUntil: () => Promise.resolve(),\n\t\t\tfinishAudio: () => Promise.resolve(),\n\t\t\tcancel: () => Promise.resolve(),","sourceCodeStart":46,"sourceCodeEnd":82,"githubUrl":"https://github.com/remotion-dev/remotion/blob/b2f4e34732f3c6c222ea029413e22dc402218cd7/packages/video-matting/src/prepare-audio.ts#L46-L82","documentation":"prepareAudio validates the audio-transcoding timestamp window before processing: videoEndTimestamp must be a finite number (a parallel check already covered videoStartTimestamp). NaN, Infinity, or a non-numeric end timestamp aborts audio preparation with a TypeError.","triggerScenarios":"Passing NaN/Infinity/-Infinity as videoEndTimestamp, often derived from undefined durations, failed parses, or infinite loop bounds.","commonSituations":"Video duration metadata unavailable (unknown-length video) leaving Infinity; parseFloat on a malformed config value; arithmetic with null.","solutions":["Fall back to a finite duration (e.g. the asset's known duration) when metadata is missing","Validate with Number.isFinite(videoEndTimestamp) before calling prepareAudio","Fix parsing of config values so they produce numbers, not NaN"],"exampleFix":"// before\nconst end = parseFloat(config.endTime); // NaN\n// after\nconst end = Number.isFinite(parseFloat(config.endTime)) ? parseFloat(config.endTime) : duration;","handlingStrategy":"validation","validationCode":"if (!Number.isFinite(videoEndTimestamp)) {\n  throw new TypeError('videoEndTimestamp must be finite before calling prepareAudio');\n}\n","typeGuard":"const isFiniteNumber = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v);\n","tryCatchPattern":"try {\n  await prepareAudio({videoEndTimestamp, ...});\n} catch (e) {\n  if (e instanceof TypeError && e.message.includes('videoEndTimestamp')) {\n    videoEndTimestamp = knownDuration;\n  }\n  throw e;\n}\n","preventionTips":["Replace unknown durations with a finite fallback instead of Infinity","Parse config values with strict number validation","Keep timestamps in a consistent unit"],"tags":["validation","timestamp","nan"],"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"}