Popmotion/popmotion · warning

Spring duration must be 10 seconds or less

Error message

Spring duration must be 10 seconds or less

What it means

`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.

Source

Thrown at packages/popmotion/src/animations/utils/find-spring.ts:26

type Resolver = (num: number) => number

const safeMin = 0.001
export const minDuration = 0.01
export const maxDuration = 10.0
export const minDamping = 0.05
export const maxDamping = 1

export function findSpring({
    duration = 800,
    bounce = 0.25,
    velocity = 0,
    mass = 1,
}: SpringOptions) {
    let envelope: Resolver
    let derivative: Resolver

    warning(
        duration <= maxDuration * 1000,
        "Spring duration must be 10 seconds or less"
    )

    let dampingRatio = 1 - bounce

    /**
     * Restrict dampingRatio and duration to within acceptable ranges.
     */
    dampingRatio = clamp(minDamping, maxDamping, dampingRatio)
    duration = clamp(minDuration, maxDuration, duration / 1000)

    if (dampingRatio < 1) {
        /**
         * Underdamped spring
         */
        envelope = (undampedFreq) => {
            const exponentialDecay = undampedFreq * dampingRatio

View on GitHub (pinned to adf681efd8)

Solutions

  1. Reduce the spring duration to 10 seconds (10000ms) or less
  2. If you need a longer, slower motion, use a tween/decay animation instead of a spring, or lower stiffness/damping appropriately
  3. Clamp/validate duration in your config layer: `Math.min(duration, 10_000)`
  4. Check whether the 10s duration is coming from a default applied to the wrong animation type

Example fix

// before
spring({ duration: 12000, bounce: 0.3 });
// after
spring({ duration: 10000, bounce: 0.3 });
Defensive patterns

Strategy: validation

Validate before calling

function safeSpringDuration(duration) {
  if (duration > 10000) {
    console.warn(`Spring duration ${duration}ms exceeds 10s max; clamping to 10000ms`);
    return 10000;
  }
  return duration;
}
// usage: spring({ duration: safeSpringDuration(duration), bounce })

Type guard

function isSpringDuration(d: number): boolean {
  return Number.isFinite(d) && d > 0 && d <= 10000;
}

Prevention

When it happens

Trigger: `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.

Common situations: 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.


AI-assisted analysis of Popmotion/popmotion@adf681efd8 (2026-09-02). Data as JSON: /api/errors/428b167b253f0079. Report an issue: GitHub.