{"record":{"id":"428b167b253f0079","repo":"Popmotion/popmotion","slug":"spring-duration-must-be-10-seconds-or-less","errorCode":null,"errorMessage":"Spring duration must be 10 seconds or less","messagePattern":"Spring duration must be 10 seconds or less","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/popmotion/src/animations/utils/find-spring.ts","lineNumber":26,"sourceCode":"\ntype Resolver = (num: number) => number\n\nconst safeMin = 0.001\nexport const minDuration = 0.01\nexport const maxDuration = 10.0\nexport const minDamping = 0.05\nexport const maxDamping = 1\n\nexport function findSpring({\n    duration = 800,\n    bounce = 0.25,\n    velocity = 0,\n    mass = 1,\n}: SpringOptions) {\n    let envelope: Resolver\n    let derivative: Resolver\n\n    warning(\n        duration <= maxDuration * 1000,\n        \"Spring duration must be 10 seconds or less\"\n    )\n\n    let dampingRatio = 1 - bounce\n\n    /**\n     * Restrict dampingRatio and duration to within acceptable ranges.\n     */\n    dampingRatio = clamp(minDamping, maxDamping, dampingRatio)\n    duration = clamp(minDuration, maxDuration, duration / 1000)\n\n    if (dampingRatio < 1) {\n        /**\n         * Underdamped spring\n         */\n        envelope = (undampedFreq) => {\n            const exponentialDecay = undampedFreq * dampingRatio","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/Popmotion/popmotion/blob/adf681efd8568ada018ce68082dbd585f25c4c7d/packages/popmotion/src/animations/utils/find-spring.ts#L8-L44","documentation":"`findSpring` derives a spring from options like stiffness/damping or a duration+bounce. It warns (via `warning`, not throw) when the requested duration exceeds `maxDuration` of 10 seconds (`duration <= maxDuration * 1000`), because the duration-based spring derivation is only designed for durations up to 10s; beyond that results become physically meaningless.","triggerScenarios":"`animate`/`spring` with `{ type: 'spring', duration: 12, bounce: 0.5 }` or a computed duration over 10000ms; very low stiffness/damping combinations that inflate the derived duration.","commonSituations":"Config-driven animations where a duration meant for tween animations (e.g. 15000ms) is reused for a spring; users 'slowing things way down' for dramatic effects; migrated configs from tween to spring.","solutions":["Reduce the spring duration to 10 seconds (10000ms) or less","If you need a longer, slower motion, use a tween/decay animation instead of a spring, or lower stiffness/damping appropriately","Clamp/validate duration in your config layer: `Math.min(duration, 10_000)`","Check whether the 10s duration is coming from a default applied to the wrong animation type"],"exampleFix":"// before\nspring({ duration: 12000, bounce: 0.3 });\n// after\nspring({ duration: 10000, bounce: 0.3 });","handlingStrategy":"validation","validationCode":"function safeSpringDuration(duration) {\n  if (duration > 10000) {\n    console.warn(`Spring duration ${duration}ms exceeds 10s max; clamping to 10000ms`);\n    return 10000;\n  }\n  return duration;\n}\n// usage: spring({ duration: safeSpringDuration(duration), bounce })","typeGuard":"function isSpringDuration(d: number): boolean {\n  return Number.isFinite(d) && d > 0 && d <= 10000;\n}","tryCatchPattern":null,"preventionTips":["Cap spring durations at 10000ms in your config layer","Use tween/decay animations for durations longer than 10s","Audit configs that share one duration value across tween and spring animations","Set a hard default (e.g. 800ms) for springs instead of inheriting tween durations"],"tags":["spring","duration","animation-config","limit"],"backgroundTag":"spring-duration-limit","analyzedSha":"adf681efd8568ada018ce68082dbd585f25c4c7d","analyzedAt":"2026-09-02T10:01:11.645Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T16:17:10.729Z"}