remotion-dev/remotion · error · Error

Expected a keyword and a length-percentage value

Error message

Expected a keyword and a length-percentage value

What it means

Thrown by parseTransformOriginXY as an internal assertion when, in the mixed keyword + length-percentage branch, it cannot locate both a keyword token and a length-percentage token. Control flow only enters that branch when exactly one of the two tokens is a keyword and the other is a length-percentage, so both should always be present; this Error is a defensive invariant check rather than a user-facing condition.

Source

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

			second.keyword,
			value,
		);
	}

	const keyword =
		first.type === 'keyword'
			? 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];
	}

View on GitHub (pinned to 78fe4bb3fd)

Solutions

  1. Report the input string that triggered it as a Remotion bug.
  2. As a workaround, rewrite the transform-origin using explicit length-percentage values for both axes.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  return interpolate(input, inputRange, outputRange, options);
} catch (err) {
  if (err instanceof Error && err.message === 'Expected a keyword and a length-percentage value') {
    // Internal assertion: report upstream and fall back to explicit length values.
    return interpolate(input, inputRange, outputRange.map(() => '50% 50%'), options);
  }
  throw err;
}

Prevention

When it happens

Trigger: Not reachable through the public interpolate() API under normal use; it would require an internal inconsistency between parseTransformOriginToken classification and the branch dispatch.

Common situations: Effectively unreachable. If observed, it indicates a bug in Remotion's transform-origin parser rather than user input.

Related errors


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