{"record":{"id":"a6b91057a7fbf44f","repo":"remotion-dev/remotion","slug":"a-duration-of-a-spring-must-be-a-number-but-is","errorCode":null,"errorMessage":"A \"duration\" of a spring must be a \"number\" but is \"${typeof dur}\"","messagePattern":"A \"duration\" of a spring must be a \"number\" but is \"(.+?)\"","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/validation/validation-spring-duration.ts","lineNumber":7,"sourceCode":"export const validateSpringDuration = (dur: unknown) => {\n\tif (typeof dur === 'undefined') {\n\t\treturn;\n\t}\n\n\tif (typeof dur !== 'number') {\n\t\tthrow new TypeError(\n\t\t\t`A \"duration\" of a spring must be a \"number\" but is \"${typeof dur}\"`,\n\t\t);\n\t}\n\n\tif (Number.isNaN(dur)) {\n\t\tthrow new TypeError(\n\t\t\t'A \"duration\" of a spring is NaN, which it must not be',\n\t\t);\n\t}\n\n\tif (!Number.isFinite(dur)) {\n\t\tthrow new TypeError(\n\t\t\t'A \"duration\" of a spring must be finite, but is ' + dur,\n\t\t);\n\t}\n\n\tif (dur <= 0) {\n\t\tthrow new TypeError(","sourceCodeStart":1,"sourceCodeEnd":25,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/validation/validation-spring-duration.ts#L1-L25","documentation":"`validateSpringDuration()` guards the optional `duration` option of Remotion's `spring()` animation helper. This branch fires when `duration` is defined (not `undefined`) but is not a `number`. The message reports the actual typeof so you can identify string/object leaks.","triggerScenarios":"Calling `spring({frame, fps, config, duration: '1s'})` or passing a non-numeric `duration` from a prop, state, or deserialized config.","commonSituations":"Authoring spring config from form input or props where duration is a string like `\"1\"`, or destructuring a config object that accidentally carries a stringified value.","solutions":["Pass `duration` as a number (seconds), e.g. `duration: 1`.","Omit `duration` entirely if you don't need it (the function returns early when `undefined`).","Coerce from input: `duration: Number(rawDuration)`."],"exampleFix":"// before\nspring({frame, fps, config, duration: '1'});\n// after\nspring({frame, fps, config, duration: 1});","handlingStrategy":"validation","validationCode":"function safeDuration(d: unknown): number | undefined {\n  if (d == null) return undefined;\n  if (typeof d !== 'number') throw new TypeError('duration must be a number');\n  return d;\n}","typeGuard":"const isOptionalNumber = (v: unknown): v is number | undefined => v == null || typeof v === 'number';","tryCatchPattern":null,"preventionTips":["Type spring config strictly: `duration?: number`.","Avoid accepting string durations from forms; coerce at the boundary.","Unit-test spring calls with omitted and numeric durations."],"tags":["validation","spring","animation","typescript","numeric"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}