Popmotion/popmotion · warning

Complex values '${origin}' and '${target}' too different to

Error message

Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.

What it means

`mixComplex` parses complex strings (e.g. box-shadows, gradients, transform strings) into arrays of numbers and colors. If the two values don't have the same structure — same color types and same quantity of numbers/colors — interpolation is impossible, so it emits this `warning` (not a throw) and falls back to an instant transition: before p>0 the origin is shown, after that the target.

Source

Thrown at packages/popmotion/src/utils/mix-complex.ts:100

    origin: string | number,
    target: string | number
): MixComplex => {
    const template = complex.createTransformer(target)
    const originStats = analyse(origin)
    const targetStats = analyse(target)

    const canInterpolate =
        originStats.numHSL === targetStats.numHSL &&
        originStats.numRGB === targetStats.numRGB &&
        originStats.numNumbers >= targetStats.numNumbers

    if (canInterpolate) {
        return pipe(
            mixArray(originStats.parsed, targetStats.parsed),
            template
        ) as MixComplex
    } else {
        warning(
            true,
            `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`
        )

        return (p: number) => `${p > 0 ? target : origin}`
    }
}

View on GitHub (pinned to adf681efd8)

Solutions

  1. Make both strings structurally identical: same color format and same count of numbers/colors
  2. Normalize all colors to one format (e.g. convert hex to rgba) before animating
  3. If an instant jump is unacceptable, animate the components separately via `animate` on individual values
  4. Heed the warning in the console — the transition is currently not interpolating smoothly

Example fix

// before
animate boxShadow: '0px 2px 4px rgba(0,0,0,0.5)' -> '1px 1px 2px #000000'
// after
animate boxShadow: '0px 2px 4px rgba(0,0,0,0.5)' -> '1px 1px 2px rgba(0,0,0,1)'
Defensive patterns

Strategy: fallback

Validate before calling

function complexShapesMatch(origin, target) {
  const nums = s => (s.match(/-?\d*\.?\d+/g) || []).length;
  const colors = s => (s.match(/(#[0-9a-f]{3,8}|rgba?\([^)]*\)|hsla?\([^)]*\))/gi) || []).length;
  return nums(origin) === nums(target) && colors(origin) === colors(target);
}
// if false, normalize the strings before animating

Try / catch

// The library already falls back to an instant jump; add your own guard:
const mixer = complexShapesMatch(origin, target)
  ? mixComplex(origin, target)
  : (() => { console.warn('Structures differ; animating a proxy instead'); return mixComplex(normalize(origin), normalize(target)); })();

Prevention

When it happens

Trigger: `mixComplex('0px 0px 0px rgba(0,0,0,0.2)', '1px 2px 3px #000000')` (mixing rgba with hex), strings with different numbers of numeric values, or animating between values where one side has an extra component.

Common situations: Animating box-shadow or filter strings authored in inconsistent formats; values pulled from CSS/design tokens where one uses hex and the other rgba; hand-edited keyframe values.

Related errors


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