sveltejs/svelte · error · Error

Cannot spring ${typeof current_value} values

Error message

Cannot spring ${typeof current_value} values

What it means

Svelte's `spring()` store animates values by ticking them toward a target. `tick_spring` only interpolates numbers, `Date`s, arrays (of interpolables), and plain objects (of interpolables). Any other type — `string`, `boolean`, `function`, `symbol`, `bigint` — falls through to the throw. The deprecated `spring()` store is the affected API.

Source

Thrown at packages/svelte/src/motion/spring.js:55

			// @ts-ignore
			return is_date(current_value) ? new Date(current_value.getTime() + d) : current_value + d;
		}
	} else if (Array.isArray(current_value)) {
		// @ts-ignore
		return current_value.map((_, i) =>
			// @ts-ignore
			tick_spring(ctx, last_value[i], current_value[i], target_value[i])
		);
	} else if (typeof current_value === 'object') {
		const next_value = {};
		for (const k in current_value) {
			// @ts-ignore
			next_value[k] = tick_spring(ctx, last_value[k], current_value[k], target_value[k]);
		}
		// @ts-ignore
		return next_value;
	} else {
		throw new Error(`Cannot spring ${typeof current_value} values`);
	}
}

/**
 * The spring function in Svelte creates a store whose value is animated, with a motion that simulates the behavior of a spring. This means when the value changes, instead of transitioning at a steady rate, it "bounces" like a spring would, depending on the physics parameters provided. This adds a level of realism to the transitions and can enhance the user experience.
 *
 * @deprecated Use [`Spring`](https://svelte.dev/docs/svelte/svelte-motion#Spring) instead
 * @template [T=any]
 * @param {T} [value]
 * @param {SpringOptions} [opts]
 * @returns {SpringStore<T>}
 */
export function spring(value, opts = {}) {
	const store = writable(value);
	const { stiffness = 0.15, damping = 0.8, precision = 0.01 } = opts;
	/** @type {number} */
	let last_time;
	/** @type {Task | null} */

View on GitHub (pinned to 20b341f100)

Solutions

  1. Use numeric values: animate numbers or arrays of numbers.
  2. For colors or strings, use `tweened()` with a custom interpolator instead of `spring()`.
  3. Ensure `.set()` always receives the same type as the initial value.

Example fix

// before
const color = spring('#fff'); // string -> throws
color.set('#000');
// after -- animate numeric channels
const r = spring(255); r.set(0);
// or use tweened for strings
import { tweened } from 'svelte/motion';
const color = tweened('#fff');
Defensive patterns

Strategy: type-guard

Validate before calling

function isSpringable(v) {
	return typeof v === 'number' || v instanceof Date || Array.isArray(v) || (typeof v === 'object' && v !== null);
}
if (!isSpringable(value)) throw new Error('spring requires a number, Date, array, or object');

Type guard

function isSpringable(v) {
	if (typeof v === 'number' || v instanceof Date) return true;
	if (Array.isArray(v)) return v.every(isSpringable);
	if (v !== null && typeof v === 'object') return Object.values(v).every(isSpringable);
	return false;
}

Prevention

When it happens

Trigger: Creating `spring(initialValue)` where `initialValue` is a string, boolean, or function; or calling `.set(newValue)` where the new value's type isn't number/date/array/object.

Common situations: Animating a color string with `spring` (use `tweened` with an interpolator or a color tween instead); initializing `spring` with `null`/`undefined`; mixing types across `.set()` calls.

Related errors


AI-assisted analysis of sveltejs/svelte@20b341f100 (2026-08-12). Data as JSON: /api/errors/5a45e7fe4325aca8. Report an issue: GitHub.