remotion-dev/remotion · error · TypeError

Cannot interpolate "${value}" because horizontal transform-o

Error message

Cannot interpolate "${value}" because horizontal transform-origin keywords must come before a length-percentage value

What it means

Thrown by parseTransformOriginXY when a horizontal keyword (left or right) is combined with a length-percentage value but the keyword comes second. Remotion requires horizontal keywords to precede the length value ("left 50%"), matching the canonical CSS authoring order it serializes. Placing the length first ("50% left") is rejected.

Source

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

			? first
			: second.type === 'keyword'
				? second
				: null;
	const length =
		first.type === 'length-percentage'
			? first.parsed
			: second.type === 'length-percentage'
				? second.parsed
				: null;
	if (keyword === null || length === null) {
		throw new Error('Expected a keyword and a length-percentage value');
	}

	const keywordIsFirst = first.type === 'keyword';

	if (keyword.keyword === 'left' || keyword.keyword === 'right') {
		if (!keywordIsFirst) {
			throw new TypeError(
				`Cannot interpolate "${value}" because horizontal transform-origin keywords must come before a length-percentage value`,
			);
		}

		return [transformOriginKeywordOptions(keyword.keyword)[0].value, length];
	}

	if (keyword.keyword === 'top' || keyword.keyword === 'bottom') {
		return [length, transformOriginKeywordOptions(keyword.keyword)[0].value];
	}

	return keywordIsFirst
		? [transformOriginCenter, length]
		: [length, transformOriginCenter];
};

const parseTransformOriginValue = (
	output: string,

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Put the horizontal keyword first: "left 50%" instead of "50% left".
  2. Drop the keyword and use explicit percentages: "0% 50%" for left, "100% 50%" for right.

Example fix

// before
interpolate(t, [0, 1], ["50% left", "50% right"]);
// after
interpolate(t, [0, 1], ["left 50%", "right 50%"]);
Defensive patterns

Strategy: validation

Validate before calling

function isCanonicalHorizontalKeywordPair(parts: string[]): boolean {
  // Reject forms like "50% left" or "10px right"
  if (parts.length !== 2) return true;
  const [a, b] = parts.map((p) => p.toLowerCase());
  const horizSecond = (a !== 'left' && a !== 'right') && (b === 'left' || b === 'right');
  return !horizSecond;
}

outputRange.filter((s) => typeof s === 'string').forEach((s) => {
  if (!isCanonicalHorizontalKeywordPair(s.trim().split(/\s+/))) {
    throw new Error('Horizontal keyword must precede the length value');
  }
});

Prevention

When it happens

Trigger: A two-component transform-origin string of the form "<length> left" or "<length> right", e.g. "50% left", "10px right".

Common situations: Writing transform-origin values in a non-canonical order; mirroring vertical syntax (which does allow the length first) onto horizontal keywords.

Related errors


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