{"record":{"id":"7a3c30b02a5745d7","repo":"remotion-dev/remotion","slug":"fps-must-not-be-nan-but-got-fps-location","errorCode":null,"errorMessage":"\"fps\" must not be NaN, but got ${fps} ${location}","messagePattern":"\"fps\" must not be NaN, but got (.+?) (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/validation/validate-fps.ts","lineNumber":19,"sourceCode":"export function validateFps(\n\tfps: unknown,\n\tlocation: string,\n\tisGif: boolean,\n): asserts fps is number {\n\tif (typeof fps !== 'number') {\n\t\tthrow new Error(\n\t\t\t`\"fps\" must be a number, but you passed a value of type ${typeof fps} ${location}`,\n\t\t);\n\t}\n\n\tif (!Number.isFinite(fps)) {\n\t\tthrow new Error(\n\t\t\t`\"fps\" must be a finite, but you passed ${fps} ${location}`,\n\t\t);\n\t}\n\n\tif (isNaN(fps)) {\n\t\tthrow new Error(`\"fps\" must not be NaN, but got ${fps} ${location}`);\n\t}\n\n\tif (fps <= 0) {\n\t\tthrow new TypeError(`\"fps\" must be positive, but got ${fps} ${location}`);\n\t}\n\n\tif (isGif && fps > 50) {\n\t\tthrow new TypeError(\n\t\t\t`The FPS for a GIF cannot be higher than 50. Use the --every-nth-frame option to lower the FPS: https://remotion.dev/docs/render-as-gif`,\n\t\t);\n\t}\n}\n","sourceCodeStart":1,"sourceCodeEnd":32,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validation/validate-fps.ts#L1-L32","documentation":"Even though `Number.isFinite(NaN)` is `false` and would be caught by the earlier `!Number.isFinite` check in practice, this branch exists as a defensive explicit NaN guard inside `validateFps()`. It signals that the caller passed `NaN` as the frame rate.","triggerScenarios":"Passing `fps={NaN}` to a composition, or a value derived from `parseInt(undefined)`, `Number(undefined)`, or `0/0`.","commonSituations":"Parsing form input where the field is empty (`Number('')` is `0`, but `parseInt(undefined)` is `NaN`), or arithmetic on `undefined` numerics.","solutions":["Replace the `NaN` source with a concrete number.","Guard the input: `const fps = Number.isNaN(raw) ? 30 : raw;`.","Trace upstream: log the value just before it is passed to find where `NaN` originates."],"exampleFix":"// before\nconst fps = parseInt(userInput.fps); // NaN when empty\n<Composition fps={fps} ... />\n// after\nconst fps = Number.parseInt(userInput.fps, 10);\n<Composition fps={Number.isNaN(fps) ? 30 : fps} ... />","handlingStrategy":"validation","validationCode":"const fps = Number.isNaN(rawFps) ? 30 : rawFps;","typeGuard":"const isValidFps = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && !Number.isNaN(v) && v > 0;","tryCatchPattern":null,"preventionTips":["Validate parsed fps with `Number.isNaN` before use.","Treat empty user input as a default, not NaN.","Audit any `parseInt`/`Number` call whose input may be undefined."],"tags":["validation","config","fps","numeric","nan"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}