remotion-dev/remotion · error · TypeError

The units of the start and end values must match. Start valu

Error message

The units of the start and end values must match. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}

What it means

Thrown by interpolateStyles when both the start and end parts are numeric but their units differ and neither value is zero. interpolateStyles allows a 0 on either side to pair with any unit (0 is unit-agnostic), but any other numeric pair must share the same unit so the numbers can be linearly blended.

Source

Thrown at packages/animation-utils/src/transformation-helpers/interpolate-styles/index.tsx:111

		}(${interpolatedFunctionArgs.slice(2)})`;
	}

	if (typeof initialStylePropertyPart.number === 'undefined') {
		if (initialStylePropertyPart.unit !== finalStylePropertyPart.unit) {
			throw new TypeError(
				`Non-animatable values cannot be interpolated. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}`,
			);
		}

		return `${initialStylePropertyPart.unit}`;
	}

	if (
		initialStylePropertyPart.unit !== finalStylePropertyPart.unit &&
		initialStylePropertyPart.number !== 0 &&
		finalStylePropertyPart.number !== 0
	) {
		throw new TypeError(
			`The units of the start and end values must match. Start value: ${initialStyleProperty}, end value: ${finalStyleProperty}`,
		);
	}

	const startNumber = initialStylePropertyPart.number;
	const endNumber = finalStylePropertyPart.number || 0;
	const interpolatedNumber = interpolate(
		inputValue,
		inputRange,
		[startNumber, endNumber],
		options,
	);
	const interpolatedUnit =
		initialStylePropertyPart.unit || finalStylePropertyPart.unit || '';

	if (!interpolatedUnit) {
		return interpolatedNumber;
	}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Convert one side so both keyframes use the same unit (e.g. '50%' to '750px' at a known container width).
  2. If you must cross units, set one side to the literal 0 (number) — 0 pairs with any unit.
  3. Pre-compute unit conversions before building the outputStyles array.

Example fix

// before
interpolateStyles(frame, [0, 30], [
  {width: '100px'},
  {width: '50%'},  // unit mismatch
]);

// after
interpolateStyles(frame, [0, 30], [
  {width: '100px'},
  {width: '750px'},  // same unit
]);
Defensive patterns

Strategy: validation

Validate before calling

const unitOf = (v: string): string => {
  const m = v.match(/^(-?\d+(?:\.\d+)?)([a-z%]*)/i);
  return m ? m[2] : '';
};
const unitsCompatible = (a: unknown, b: unknown): boolean => {
  if (typeof a === 'number' || typeof b === 'number') return true; // 0 is unit-agnostic
  if (typeof a === 'string' && typeof b === 'string') {
    return unitOf(a) === unitOf(b);
  }
  return false;
};

Prevention

When it happens

Trigger: Keyframes like {width: '100px'} to {width: '50%'}; or {transform: 'translate(10px,0)'} to {transform: 'translate(0,1em)'} where the non-zero sides use different units.

Common situations: Mixing px and % across keyframes; switching between rem and px; copy-pasting values from design tools that use different units.

Related errors


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