{"record":{"id":"e1733b9b33b62cc4","repo":"remotion-dev/remotion","slug":"argument-for-frame-must-be-an-integer-but-got-f","errorCode":null,"errorMessage":"Argument for frame must be an integer, but got ${frame}","messagePattern":"Argument for frame must be an integer, but got (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/validate-frame.ts","lineNumber":25,"sourceCode":"\tdurationInFrames: number;\n\tallowFloats: boolean;\n}) => {\n\tif (typeof frame === 'undefined') {\n\t\tthrow new TypeError(`Argument missing for parameter \"frame\"`);\n\t}\n\n\tif (typeof frame !== 'number') {\n\t\tthrow new TypeError(\n\t\t\t`Argument passed for \"frame\" is not a number: ${frame}`,\n\t\t);\n\t}\n\n\tif (!Number.isFinite(frame)) {\n\t\tthrow new RangeError(`Frame ${frame} is not finite`);\n\t}\n\n\tif (frame % 1 !== 0 && !allowFloats) {\n\t\tthrow new RangeError(\n\t\t\t`Argument for frame must be an integer, but got ${frame}`,\n\t\t);\n\t}\n\n\tif (frame < 0 && frame < -durationInFrames) {\n\t\tthrow new RangeError(\n\t\t\t`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the lowest frame that can be rendered is ${-durationInFrames}`,\n\t\t);\n\t}\n\n\tif (frame > durationInFrames - 1) {\n\t\tthrow new RangeError(\n\t\t\t`Cannot use frame ${frame}: Duration of composition is ${durationInFrames}, therefore the highest frame that can be rendered is ${\n\t\t\t\tdurationInFrames - 1\n\t\t\t}`,\n\t\t);\n\t}\n};","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validate-frame.ts#L7-L43","documentation":"validateFrame throws a RangeError when frame is a non-integer (has a fractional part) and the caller did not enable `allowFloats`. Most Remotion APIs operate on integer frame indices; floating-point frames are only valid in specific sub-APIs that pass allowFloats=true.","triggerScenarios":"Passing a float (e.g. 12.5) to an integer-only API like seekTo or timeline registration without allowFloats; computing frame from sub-frame math; rounding errors leaving a tiny fractional component like 12.0000000001.","commonSituations":"Interpolating/extrapolating to a frame and forgetting to round; dividing time by fps yielding a fractional frame; mixing continuous-time APIs with integer-frame APIs.","solutions":["Round to the nearest integer: `Math.round(frame)` or `Math.floor(frame)` before passing.","If you genuinely need sub-frame precision, use an API path that passes allowFloats=true (interpolation inputs).","Sanitize floating-point: `Math.round(frame * 1e6) / 1e6` to kill rounding dust, then round.","Confirm which API you are calling — most player/timeline calls want integers."],"exampleFix":"// before\nconst frame = timeSeconds * fps; // 12.5\nseekTo(frame);\n\n// after\nconst frame = Math.round(timeSeconds * fps);\nseekTo(frame);","handlingStrategy":"validation","validationCode":"const intFrame = Math.round(frame);\nvalidateFrame({ frame: intFrame, durationInFrames, allowFloats });","typeGuard":"const isIntegerFrame = (f: unknown): f is number => typeof f === 'number' && Number.isInteger(f);","tryCatchPattern":null,"preventionTips":["Round frames (Math.round/Math.floor) before passing to integer-only APIs.","Only enable allowFloats on APIs designed for sub-frame precision.","Beware floating-point dust: round after multiplication."],"tags":["remotion","frame","validation","rangeerror","integer","floating-point"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}