{"record":{"id":"1e6808d811b7597e","repo":"remotion-dev/remotion","slug":"fps-must-be-positive-but-got-fps-location","errorCode":null,"errorMessage":"\"fps\" must be positive, but got ${fps} ${location}","messagePattern":"\"fps\" must be positive, but got (.+?) (.+?)","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/validation/validate-fps.ts","lineNumber":23,"sourceCode":"): 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":5,"sourceCodeEnd":32,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validation/validate-fps.ts#L5-L32","documentation":"`validateFps()` throws a `TypeError` when `fps <= 0` because a video must have at least one frame per second for time math to be meaningful. This is thrown as a `TypeError` (unlike the prior `Error` throws) because a non-positive number is a type-level contract violation for a frame rate.","triggerScenarios":"Passing `fps={0}`, `fps={-30}`, or any non-positive numeric value into a composition, `<Sequence>`, or any API that ultimately calls `validateFps`.","commonSituations":"Subtracting from fps accidentally (`fps={base - offset}` where offset exceeds base), defaulting fps to `0` as a placeholder, or sign errors from user input parsing.","solutions":["Set fps to a positive number, conventionally `30` or higher.","Clamp computed values: `const fps = Math.max(1, computed);`.","Inspect the `${location}` to find which composition is at fault."],"exampleFix":"// before\n<Composition fps={0} ... />\n// after\n<Composition fps={30} ... />","handlingStrategy":"validation","validationCode":"const fps = Math.max(1, Number(rawFps));","typeGuard":"const isPositiveFps = (v: unknown): v is number => typeof v === 'number' && v > 0;","tryCatchPattern":null,"preventionTips":["Default fps to a positive constant (e.g. 30).","Clamp computed fps with `Math.max(1, value)`.","Avoid subtraction that can drive fps below 1."],"tags":["validation","config","fps","numeric"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}