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
- Convert one side so both keyframes use the same unit (e.g. '50%' to '750px' at a known container width).
- If you must cross units, set one side to the literal 0 (number) — 0 pairs with any unit.
- 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
- Use a single unit (preferably px or %) for a property across all keyframes.
- Convert units up front before building the outputStyles array.
- Use the literal 0 (number) to cross unit boundaries safely.
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
- The start and end values must be of the same type. Start val
- Non-animatable values cannot be interpolated. Start value: $
- The start and end values must have the same structure. Start
- input ${input} does not end with a valid unit. Valid units a
- input ${input} is not a valid transform. Must be a number or
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/59eb8157889ffa2c.
Report an issue: GitHub.