{"record":{"id":"0889abf7b29c764f","repo":"remotion-dev/remotion","slug":"extrapolateright-identity-is-not-supported-for","errorCode":null,"errorMessage":"extrapolateRight: \"identity\" is not supported for non-numeric strings","messagePattern":"extrapolateRight: \"identity\" is not supported for non-numeric strings","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/interpolate.ts","lineNumber":931,"sourceCode":"\t\tif (options?.extrapolateLeft === 'identity') {\n\t\t\tthrow new TypeError(\n\t\t\t\t'extrapolateLeft: \"identity\" is not supported for non-numeric strings',\n\t\t\t);\n\t\t}\n\n\t\tif (options?.extrapolateLeft === 'wrap') {\n\t\t\tconst wrapRange = inputMax - inputMin;\n\t\t\tresolvedInput =\n\t\t\t\t((((resolvedInput - inputMin) % wrapRange) + wrapRange) % wrapRange) +\n\t\t\t\tinputMin;\n\t\t} else {\n\t\t\treturn outputRange[0];\n\t\t}\n\t}\n\n\tif (resolvedInput > inputMax) {\n\t\tif (options?.extrapolateRight === 'identity') {\n\t\t\tthrow new TypeError(\n\t\t\t\t'extrapolateRight: \"identity\" is not supported for non-numeric strings',\n\t\t\t);\n\t\t}\n\n\t\tif (options?.extrapolateRight === 'wrap') {\n\t\t\tconst wrapRange = inputMax - inputMin;\n\t\t\tresolvedInput =\n\t\t\t\t((((resolvedInput - inputMin) % wrapRange) + wrapRange) % wrapRange) +\n\t\t\t\tinputMin;\n\t\t} else {\n\t\t\treturn outputRange[outputRange.length - 1];\n\t\t}\n\t}\n\n\tconst range = findRange(resolvedInput, inputRange);\n\treturn resolvedInput >= inputRange[range + 1]\n\t\t? outputRange[range + 1]\n\t\t: outputRange[range];","sourceCodeStart":913,"sourceCodeEnd":949,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/interpolate.ts#L913-L949","documentation":"Thrown by interpolateDiscreteString when input exceeds the last inputRange value and options.extrapolateRight is 'identity'. As with the left side, identity extrapolation has no meaningful numeric return for a non-numeric string outputRange, so it is rejected.","triggerScenarios":"interpolate(t, [0, 1], [\"red\", \"blue\"], {easing: Easing.step1, extrapolateRight: 'identity'}) called with t > 1.","commonSituations":"Carrying 'identity' right-extrapolation over from a numeric interpolate() call to a discrete string call; ranges where the input can overshoot the top.","solutions":["Use extrapolateRight: 'clamp' (returns the last output), 'extend', or 'wrap'.","Clamp the input before calling interpolate()."],"exampleFix":"// before\ninterpolate(t, [0, 1], [\"red\", \"blue\"], {\n  easing: Easing.step1,\n  extrapolateRight: 'identity',\n});\n// after\ninterpolate(t, [0, 1], [\"red\", \"blue\"], {\n  easing: Easing.step1,\n  extrapolateRight: 'clamp',\n});","handlingStrategy":"validation","validationCode":"function isDiscreteStringRange(outputRange: readonly (string | number)[]): boolean {\n  return outputRange.some((o) => typeof o === 'string'\n    && o.trim().split(/\\s+/).some((p) => !/^([+-]?(?:\\d+\\.?\\d*|\\.\\d+))([a-zA-Z%]+)?$/.test(p)\n      && !/^(left|right|top|bottom|center)$/i.test(p)));\n}\n\nif (isDiscreteStringRange(outputRange) && options?.extrapolateRight === 'identity') {\n  throw new Error('Use extrapolateRight: clamp|extend|wrap for discrete strings');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["For non-numeric string ranges use extrapolateRight: 'clamp', 'extend', or 'wrap' — never 'identity'.","Clamp the input upstream so it cannot exceed the last inputRange value."],"tags":["interpolate","discrete-string","extrapolation","validation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}