remotion-dev/remotion · error · Error

easing[${i}] must be a function

Error message

easing[${i}] must be a function

What it means

Thrown by assertValidInterpolateEasingOption while iterating the easing array. Each entry must be a function (an easing function); a non-function entry (number, string, null, undefined) is rejected.

Source

Thrown at packages/core/src/interpolate.ts:1059

) {
	if (easing === undefined) {
		return;
	}

	if (typeof easing === 'function') {
		return;
	}

	const expectedLength = inputRangeLength - 1;
	if (easing.length !== expectedLength) {
		throw new Error(
			`When easing is an array, it must have one entry per segment between keyframes (length inputRange.length - 1 = ${expectedLength}), but got length ${easing.length}`,
		);
	}

	for (let i = 0; i < easing.length; i++) {
		if (typeof easing[i] !== 'function') {
			throw new Error(`easing[${i}] must be a function`);
		}
	}
}

export function assertValidInterpolatePosterizeOption(
	posterize: number | undefined,
) {
	if (posterize === undefined) {
		return;
	}

	if (
		typeof posterize !== 'number' ||
		!Number.isFinite(posterize) ||
		posterize <= 0
	) {
		throw new Error(
			`posterize must be a positive finite number, but got ${posterize}`,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Pass actual easing function references from the Easing module, not their names.
  2. Map any serialized easing names to functions via a lookup table before calling interpolate().
  3. Drop undefined/null entries from the easing array.

Example fix

// before
const r = interpolate(t, [0, 1], [0, 100], {easing: ['easeIn']});
// after
import {Easing} from 'remotion';
const r = interpolate(t, [0, 1], [0, 100], {easing: [Easing.in(Easing.ease)]});
Defensive patterns

Strategy: type-guard

Validate before calling

if (Array.isArray(easing) && !easing.every((e) => typeof e === 'function')) {
  throw new Error('every easing entry must be a function');
}
const r = interpolate(input, inputRange, outputRange, {easing});

Type guard

const isEasingFunctionArray = (
  e: unknown,
): e is ((t: number) => number)[] =>
  Array.isArray(e) && e.every((f) => typeof f === 'function');

Prevention

When it happens

Trigger: interpolate(t, [0,1], [0,100], {easing: ['easeIn']}); passing the name of an easing as a string instead of the function reference; an array like [Easing.linear, null, Easing.ease] with a gap.

Common situations: Confusing easing identifiers/names with the easing functions themselves; deserializing easing config from JSON (functions cannot be serialized) and passing the raw strings.

Related errors


AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12). Data as JSON: /api/errors/dc06e3349dfd6f88. Report an issue: GitHub.