{"record":{"id":"b70e49b5e838f7b6","repo":"remotion-dev/remotion","slug":"inputrange-must-be-strictly-monotonically-non-decr","errorCode":null,"errorMessage":"inputRange must be strictly monotonically non-decreasing but got [${arr.join(',')}]","messagePattern":"inputRange must be strictly monotonically non-decreasing but got \\[(.+?)\\]","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/animation-utils/src/transformation-helpers/interpolate-styles/index.tsx","lineNumber":250,"sourceCode":"\tif (arr.length < 2) {\n\t\tthrow new Error('inputRange must have at least 2 elements');\n\t}\n\n\tfor (let index = 0; index < arr.length; index++) {\n\t\tif (typeof arr[index] !== 'number') {\n\t\t\tthrow new Error(`inputRange must contain only numbers`);\n\t\t}\n\n\t\tif (arr[index] === -Infinity || arr[index] === Infinity) {\n\t\t\tthrow new Error(\n\t\t\t\t`inputRange must contain only finite numbers, but got [${arr.join(\n\t\t\t\t\t',',\n\t\t\t\t)}]`,\n\t\t\t);\n\t\t}\n\n\t\tif (index > 0 && !(arr[index] > arr[index - 1])) {\n\t\t\tthrow new Error(\n\t\t\t\t`inputRange must be strictly monotonically non-decreasing 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 checkStylesRange(arr: readonly Style[]) {\n\tif (arr.length < 2) {\n\t\tthrow new Error('outputStyles must have at least 2 elements');\n\t}\n\n\tfor (const index in arr) {\n\t\tif (typeof arr[index] !== 'object') {\n\t\t\tthrow new Error('outputStyles must contain only objects');\n\t\t}\n\t}","sourceCodeStart":232,"sourceCodeEnd":268,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/animation-utils/src/transformation-helpers/interpolate-styles/index.tsx#L232-L268","documentation":"Thrown by checkInputRange when the array is not strictly increasing. Each element must be greater than the previous one; equal or decreasing values are rejected because they create ambiguous or inverted interpolation segments. Note: the message says 'non-decreasing' but the check (arr[index] > arr[index - 1]) enforces strictly increasing — equal values also fail.","triggerScenarios":"Passing [0, 0], [30, 10], or [0, 10, 10, 20]; duplicate frame values from two keyframes at the same frame; a reversed keyframe order.","commonSituations":"Two keyframes sharing the same frame number; generating a range from unsorted data; copy-paste producing duplicates; rounding that collapses two distinct frames to the same integer.","solutions":["Sort the range ascending and remove duplicates before calling interpolateStyles.","Ensure each keyframe frame number is strictly greater than the previous one.","Dedupe dynamic arrays with [...new Set(arr)].sort((a, b) => a - b)."],"exampleFix":"// before\ninterpolateStyles(frame, [0, 10, 10, 30], [...]);\n\n// after\ninterpolateStyles(frame, [0, 10, 30], [...]);","handlingStrategy":"validation","validationCode":"const isStrictlyIncreasing = (arr: number[]): boolean =>\n  arr.every((x, i) => i === 0 || x > arr[i - 1]);\nif (!isStrictlyIncreasing(inputRange)) {\n  // dedupe + sort\n  inputRange = [...new Set(inputRange)].sort((a, b) => a - b);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Sort and dedupe dynamic ranges before calling interpolateStyles.","Ensure keyframe frame numbers are strictly increasing when authoring.","Remember the check is strictly increasing, despite the 'non-decreasing' wording."],"tags":["interpolate-styles","input-range","validation","sorting"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}