Popmotion/popmotion · error

Both input and output ranges must be the same length

Error message

Both input and output ranges must be the same length

What it means

This invariant in `interpolate` enforces that the input range and output range arrays have exactly the same number of entries, because each input value maps 1:1 to an output value when interpolating. The library throws immediately (via `invariant`) rather than guessing a mapping, since a length mismatch makes the interpolation undefined. It applies to `interpolate`/`createInterpolator` and any `animate` call that ends up building an interpolator.

Source

Thrown at packages/popmotion/src/utils/interpolate.ts:125

 *   - Colors (hex, hsl, hsla, rgb, rgba)
 *   - Complex (combinations of one or more numbers or strings)
 *
 * ```jsx
 * const mixColor = interpolate([0, 1], ['#fff', '#000'])
 *
 * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
 * ```
 *
 * @public
 */
export function interpolate<T>(
  input: number[],
  output: T[],
  { clamp: isClamp = true, ease, mixer }: InterpolateOptions<T> = {}
) {
  const inputLength = input.length;

  invariant(
    inputLength === output.length,
    'Both input and output ranges must be the same length'
  );

  invariant(
    !ease || !Array.isArray(ease) || ease.length === inputLength - 1,
    'Array of easing functions must be of length `input.length - 1`, as it applies to the transitions **between** the defined values.'
  );

  // If input runs highest -> lowest, reverse both arrays
  if (input[0] > input[inputLength - 1]) {
    input = [].concat(input);
    output = [].concat(output);
    input.reverse();
    output.reverse();
  }

  const mixers = createMixers(output, ease, mixer);

View on GitHub (pinned to adf681efd8)

Solutions

  1. Make `output.length === input.length` — every input stop must have exactly one corresponding output value
  2. Log both arrays (`input.length` vs `output.length`) before the call to find which is wrong
  3. If you intended the same output over a range, repeat the value, e.g. `interpolate([0,0.5,1],['0px','0px','100px'])`
  4. Validate dynamic keyframe data before passing it to `animate`/`interpolate`

Example fix

// before
const x = interpolate([0, 0.5, 1], ['0px', '100px']);
// after
const x = interpolate([0, 0.5, 1], ['0px', '100px', '200px']);
Defensive patterns

Strategy: validation

Validate before calling

function validateRanges(input, output) {
  if (input.length !== output.length) {
    throw new Error(`interpolate: input has ${input.length} stops but output has ${output.length} values`);
  }
  return [input, output];
}
// usage: validateRanges(input, output) before calling interpolate(input, output)

Type guard

function hasMatchingRanges<T>(input: number[], output: T[]): input is number[] & { length: T['length'] } {
  return input.length === output.length;
}

Prevention

When it happens

Trigger: Calling `interpolate([0, 0.5, 1], ['0px', '100px'])` (output has fewer items), or `interpolate([0, 1], ['0px','50px','100px'])`, or passing a mismatched range array from dynamic data (e.g. keyframe arrays built at runtime) into `createInterpolator`/`animate`.

Common situations: Generating keyframes programmatically where a value is added to one array but not the other; refactoring code and removing an output value while leaving the input stops; passing user-supplied keyframe configs of unequal length.

Related errors


AI-assisted analysis of Popmotion/popmotion@adf681efd8 (2026-09-02). Data as JSON: /api/errors/08a11f5490c9f1d0. Report an issue: GitHub.