heygen-com/hyperframes · error · RangeError

Color curve inputs must be strictly increasing

Error message

Color curve inputs must be strictly increasing

What it means

validateCurvePoints() requires the input (first element) of each point to be strictly greater than the previous point's input. Equal or decreasing inputs are rejected because they produce zero or negative spans, which break the slope math (division by span) and create ambiguous segments. The check seeds previousInput at -Infinity so the first real point always passes.

Source

Thrown at packages/core/src/colorGradingCurves.ts:83

    const beforeWeight = 2 * afterSpan + beforeSpan;
    const afterWeight = afterSpan + 2 * beforeSpan;
    result[index] = (beforeWeight + afterWeight) / (beforeWeight / before + afterWeight / after);
  }
  return result;
}

function validateCurvePoints(points: readonly HfColorCurvePoint[], size: number): void {
  if (points.length < 2) throw new RangeError("A color curve requires at least two points");
  if (!Number.isInteger(size) || size < 2) {
    throw new RangeError("Curve LUT size must be at least 2");
  }
  let previousInput = Number.NEGATIVE_INFINITY;
  for (const [input, output] of points) {
    if (!Number.isFinite(input) || !Number.isFinite(output)) {
      throw new TypeError("Color curve points must be finite");
    }
    if (input <= previousInput) {
      throw new RangeError("Color curve inputs must be strictly increasing");
    }
    previousInput = input;
  }
}

function validateOutputRange(
  points: readonly HfColorCurvePoint[],
  outputMin: number,
  outputMax: number,
): void {
  if (!Number.isFinite(outputMin) || !Number.isFinite(outputMax) || outputMin >= outputMax) {
    throw new RangeError("Curve output bounds must be finite and increasing");
  }
  if (points.some(([, output]) => output < outputMin || output > outputMax)) {
    throw new RangeError(`Curve outputs must be between ${outputMin} and ${outputMax}`);
  }
}

View on GitHub (pinned to c2996c8626)

Solutions

  1. Sort points by input ascending and deduplicate exact-input collisions before compiling.
  2. Prevent the UI from letting two points occupy the same x (snap/nudge on drop).

Example fix

// before
compileHfColorCurve([[0, 0], [0.5, 0.2], [0.5, 0.8], [1, 1]]); // duplicate input 0.5

// after — sort + dedupe by input
const dedup = new Map<number, number>();
for (const [i, o] of pts) dedup.set(i, o);
const sorted = [...dedup].sort((a, b) => a[0] - b[0]);
compileHfColorCurve(sorted);
Defensive patterns

Strategy: validation

Validate before calling

const sorted = [...new Map(points.map(([i,o]) => [i,o]))].sort((a,b) => a[0]-b[0]);
// sorted now has strictly increasing inputs

Type guard

function inputsStrictlyIncreasing(points: readonly (readonly [number, number)[]): boolean {
  for (let i = 1; i < points.length; i++) if (points[i][0] <= points[i-1][0]) return false;
  return true;
}

Try / catch

try { compileHfColorCurve(pts); }
catch (err) { if (/strictly increasing/.test(String(err))) { /* sort + dedupe by input */ } else throw err; }

Prevention

When it happens

Trigger: Two points with the same input (e.g. [[0,0],[0.5,0.2],[0.5,0.8],[1,1]]); inputs out of order ([[0,0],[1,1],[0.5,0.5]]); duplicate endpoints.

Common situations: A curve editor that lets two control points share an x coordinate; copy-paste duplicating a point; an unsorted array passed directly.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/39314d620b734eb6. Report an issue: GitHub.