{"record":{"id":"e6255930afaa666f","repo":"remotion-dev/remotion","slug":"inputrange-must-be-strictly-monotonically-increasi","errorCode":null,"errorMessage":"inputRange must be strictly monotonically increasing but got [${arr.join(',')}]","messagePattern":"inputRange must be strictly monotonically increasing but got \\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/core/src/interpolate.ts","lineNumber":1011,"sourceCode":"\toutputRange: readonly (readonly unknown[])[];\n\toptions: InterpolateOptions | undefined;\n}): number[] => {\n\tconst dimensions = validateTupleOutputRange(outputRange);\n\n\treturn new Array(dimensions).fill(true).map((_, axis) =>\n\t\tinterpolateNumber({\n\t\t\tinput,\n\t\t\tinputRange,\n\t\t\toutputRange: outputRange.map((output) => output[axis] as number),\n\t\t\toptions,\n\t\t}),\n\t);\n};\n\nfunction checkValidInputRange(arr: readonly number[]) {\n\tfor (let i = 1; i < arr.length; ++i) {\n\t\tif (!(arr[i] > arr[i - 1])) {\n\t\t\tthrow new Error(\n\t\t\t\t`inputRange must be strictly monotonically increasing but got [${arr.join(\n\t\t\t\t\t',',\n\t\t\t\t)}]`,\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction checkInfiniteRange(name: string, arr: readonly number[]) {\n\tif (arr.length < 1) {\n\t\tthrow new Error(name + ' must have at least 1 element');\n\t}\n\n\tfor (const element of arr) {\n\t\tif (typeof element !== 'number') {\n\t\t\tthrow new Error(`${name} must contain only numbers`);\n\t\t}\n","sourceCodeStart":993,"sourceCodeEnd":1029,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/core/src/interpolate.ts#L993-L1029","documentation":"Thrown by checkValidInputRange. The inputRange for interpolate() must be strictly monotonically increasing: each value must be greater than the previous one. Equal adjacent values and any decrease both trigger it, because interpolation cannot resolve a segment with zero or negative width.","triggerScenarios":"Passing inputRange with duplicate values, e.g. interpolate(0, [0, 0, 1], [...]); a decreasing range like [1, 0]; or an unsorted array built from a Set/Map whose insertion order is not ascending.","commonSituations":"Deriving keyframes from data (CSV, JSON, props) without sorting; copy-paste keyframes that reuse the same timestamp; rounding that collapses two distinct times to the same number.","solutions":["Sort the inputRange ascending and dedupe it before calling interpolate().","Inspect the rendered array in the error message ([${arr.join(',')}]) to find the duplicate/decrease.","Regenerate keyframes so each timestamp is strictly greater than the prior one."],"exampleFix":"// before\nconst r = interpolate(t, [0, 0, 1], [0, 50, 100]);\n// after\nconst r = interpolate(t, [0, 1], [0, 100]);","handlingStrategy":"validation","validationCode":"const isStrictlyIncreasing = (arr: readonly number[]) =>\n  arr.every((v, i) => i === 0 || v > arr[i - 1]);\n\nif (!isStrictlyIncreasing(inputRange)) {\n  throw new Error('inputRange must be strictly increasing');\n}\nconst r = interpolate(input, inputRange, outputRange);","typeGuard":"const isStrictlyIncreasing = (arr: readonly number[]): boolean =>\n  arr.every((v, i) => i === 0 || v > arr[i - 1]);","tryCatchPattern":null,"preventionTips":["Sort and dedupe keyframe times before building inputRange.","Keep keyframes in a single source-of-truth array so inputRange stays in sync.","Add a unit test asserting monotonicity for data-driven ranges."],"tags":["interpolation","validation","input-range"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}