{"record":{"id":"249a2cfa5cf875ac","repo":"remotion-dev/remotion","slug":"threshold-is-below-0","errorCode":null,"errorMessage":"Threshold is below 0","messagePattern":"Threshold is below 0","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/spring/measure-spring.ts","lineNumber":51,"sourceCode":"\n\tif (threshold === 0) {\n\t\treturn Infinity;\n\t}\n\n\tif (threshold === 1) {\n\t\treturn 0;\n\t}\n\n\tif (isNaN(threshold)) {\n\t\tthrow new TypeError('Threshold is NaN');\n\t}\n\n\tif (!Number.isFinite(threshold)) {\n\t\tthrow new TypeError('Threshold is not finite');\n\t}\n\n\tif (threshold < 0) {\n\t\tthrow new TypeError('Threshold is below 0');\n\t}\n\n\tconst cacheKey = [\n\t\tfps,\n\t\tconfig.damping,\n\t\tconfig.mass,\n\t\tconfig.overshootClamping,\n\t\tconfig.stiffness,\n\t\tthreshold,\n\t].join('-');\n\tif (cache.has(cacheKey)) {\n\t\treturn cache.get(cacheKey)!;\n\t}\n\n\tvalidateFps(fps, 'to the measureSpring() function', false);\n\n\tlet frame = 0;\n\tlet finishedFrame = 0;","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/spring/measure-spring.ts#L33-L69","documentation":"measureSpring()'s `threshold` represents the maximum distance from the target value at which the spring is considered settled, so it must be non-negative. This guard rejects any negative threshold, which would never be satisfied by an absolute difference and would loop forever.","triggerScenarios":"Calling `measureSpring({fps, threshold: -0.1})` or passing a computed threshold that went negative, e.g. `a - b` where `a < b`, or a sign error in configuration.","commonSituations":"Off-by-one or sign mistakes when deriving threshold from offsets; reusing a 'tolerance' variable that holds a signed delta.","solutions":["Pass a positive threshold (typical values are between 0 and 1, e.g. 0.005).","Wrap computed thresholds with `Math.abs(...)` before passing.","Validate `threshold >= 0` before calling measureSpring()."],"exampleFix":"// before\nconst dur = measureSpring({fps: 30, threshold: target - current});\n\n// after\nconst dur = measureSpring({fps: 30, threshold: Math.abs(target - current)});","handlingStrategy":"validation","validationCode":"const threshold = computeThreshold();\nif (typeof threshold !== 'number' || threshold < 0) {\n  throw new Error(`threshold must be >= 0, got ${threshold}`);\n}\nconst dur = measureSpring({fps: 30, threshold});","typeGuard":"const isNonNegativeFinite = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0;","tryCatchPattern":null,"preventionTips":["Wrap computed thresholds with Math.abs() when they represent a tolerance.","Keep threshold in the (0, 1] range to match the spring's normalized output.","Name tolerance variables clearly (e.g. `absTolerance`) to signal sign expectations."],"tags":["spring","animation","validation","measure-spring","negative-value"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}