remotion-dev/remotion · error · TypeError
extrapolateLeft: "identity" is not supported for non-numeric
Error message
extrapolateLeft: "identity" is not supported for non-numeric strings
What it means
Thrown by interpolateDiscreteString when input is below inputRange[0] and options.extrapolateLeft is 'identity'. Identity extrapolation would return the raw (sub-min) input as a number, but a discrete non-numeric string outputRange has no numeric value to return, so the combination is rejected.
Source
Thrown at packages/core/src/interpolate.ts:914
}) !== Easing.step1
) {
throw new TypeError(
'Non-numeric strings can only be interpolated using Easing.step1',
);
}
}
const posterizedInput =
options?.posterize === undefined
? input
: Math.floor(input / options.posterize) * options.posterize;
const inputMin = inputRange[0];
const inputMax = inputRange[inputRange.length - 1];
let resolvedInput = posterizedInput;
if (resolvedInput < inputMin) {
if (options?.extrapolateLeft === 'identity') {
throw new TypeError(
'extrapolateLeft: "identity" is not supported for non-numeric strings',
);
}
if (options?.extrapolateLeft === 'wrap') {
const wrapRange = inputMax - inputMin;
resolvedInput =
((((resolvedInput - inputMin) % wrapRange) + wrapRange) % wrapRange) +
inputMin;
} else {
return outputRange[0];
}
}
if (resolvedInput > inputMax) {
if (options?.extrapolateRight === 'identity') {
throw new TypeError(
'extrapolateRight: "identity" is not supported for non-numeric strings',View on GitHub (pinned to 78fe4bb3fd)
Solutions
- Use extrapolateLeft: 'clamp' (default discrete behavior returns the first output) or 'extend' for non-numeric strings.
- Guard the input so it never falls below inputRange[0].
- Switch to extrapolateLeft: 'wrap' to cycle through outputs.
Example fix
// before
interpolate(t, [0, 1], ["red", "blue"], {
easing: Easing.step1,
extrapolateLeft: 'identity',
});
// after
interpolate(t, [0, 1], ["red", "blue"], {
easing: Easing.step1,
extrapolateLeft: 'clamp',
}); Defensive patterns
Strategy: validation
Validate before calling
function isDiscreteStringRange(outputRange: readonly (string | number)[]): boolean {
return outputRange.some((o) => typeof o === 'string'
&& o.trim().split(/\s+/).some((p) => !/^([+-]?(?:\d+\.?\d*|\.\d+))([a-zA-Z%]+)?$/.test(p)
&& !/^(left|right|top|bottom|center)$/i.test(p)));
}
if (isDiscreteStringRange(outputRange) && options?.extrapolateLeft === 'identity') {
throw new Error('Use extrapolateLeft: clamp|extend|wrap for discrete strings');
} Prevention
- For non-numeric string ranges use extrapolateLeft: 'clamp', 'extend', or 'wrap' — never 'identity'.
- Clamp the input upstream so it cannot fall below inputRange[0].
When it happens
Trigger: interpolate(t, [0, 1], ["red", "blue"], {easing: Easing.step1, extrapolateLeft: 'identity'}) called with t < 0.
Common situations: Reusing options from a numeric interpolate() call (where 'identity' is valid) on a discrete string call; animating a property whose input can undershoot the range.
Related errors
- extrapolateRight: "identity" is not supported for non-numeri
- Non-numeric strings can only be interpolated using Easing.st
- bezier x values must be in [0, 1] range
- invalid color string ${color} provided
- input can not be undefined
AI-assisted analysis of remotion-dev/remotion@78fe4bb3fd (2026-08-12).
Data as JSON: /api/errors/3cc0369019cb84d9.
Report an issue: GitHub.