remotion-dev/remotion · error · Error
Spring damping must be greater than 0, otherwise the spring(
Error message
Spring damping must be greater than 0, otherwise the spring() animation will never end, causing an infinite loop.
What it means
spring() and measureSpring() accept a `config` object with `damping`, `mass`, and `stiffness`. Damping represents the friction that lets the spring settle; with damping <= 0 the spring oscillates forever and the animation never ends. The library refuses to compute such a config to prevent infinite loops in both rendering and the measureSpring settling loop.
Source
Thrown at packages/core/src/spring/spring-utils.ts:39
};
const advanceCache: {[key: string]: AnimationNode} = {};
function advance({
animation,
now,
config,
}: {
animation: AnimationNode;
now: number;
config: SpringConfig;
}): AnimationNode {
const {toValue, lastTimestamp, current, velocity} = animation;
const deltaTime = Math.min(now - lastTimestamp, 64);
if (config.damping <= 0) {
throw new Error(
'Spring damping must be greater than 0, otherwise the spring() animation will never end, causing an infinite loop.',
);
}
const c = config.damping;
const m = config.mass;
const k = config.stiffness;
const cacheKey = [
toValue,
lastTimestamp,
current,
velocity,
c,
m,
k,
now,
].join('-');View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Set damping to a positive number; the Remotion default is 10.
- If you want a bouncy spring, increase stiffness and overshootClamping rather than zeroing damping.
- Validate `config.damping > 0` (and ideally mass > 0, stiffness > 0) before calling spring/measureSpring.
Example fix
// before
spring({fps, frame, config: {damping: 0, mass: 1, stiffness: 100}});
// after
spring({fps, frame, config: {damping: 10, mass: 1, stiffness: 100}}); Defensive patterns
Strategy: validation
Validate before calling
const config = {damping, mass: 1, stiffness: 100, overshootClamping: false};
if (!(config.damping > 0)) {
throw new Error(`damping must be > 0, got ${config.damping}`);
}
const value = spring({fps: 30, frame: 0, config}); Type guard
const isValidSpringConfig = ( c: Partial<SpringConfig>, ): c is SpringConfig => typeof c.damping === 'number' && c.damping > 0 && typeof c.mass === 'number' && c.mass > 0 && typeof c.stiffness === 'number' && c.stiffness > 0;
Prevention
- Use the default config ({damping: 10, mass: 1, stiffness: 100}) unless you have a reason to change it.
- Bound any UI control that feeds damping to a minimum above 0 (e.g. 1).
- Document the meaning of damping in your config schema so contributors do not zero it.
When it happens
Trigger: Calling `spring({fps, frame, config: {damping: 0, ...}})` or `measureSpring({fps, config: {damping: 0}})`; also fires when damping is computed and underflows to 0 or a negative number.
Common situations: Passing `{damping: 0}` thinking it means 'no friction'; typos like `damping: -1`; parameterizing damping from a UI control that can reach zero; copying configs from examples that used a different spring library.
Related errors
- Threshold is NaN
- Threshold is not finite
- Threshold is below 0
- A "duration" of a spring must be a "number" but is "${typeof
- A "duration" of a spring is NaN, which it must not be
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/477afc47ab2b77c9.
Report an issue: GitHub.