{"record":{"id":"69ce8230389fb530","repo":"heygen-com/hyperframes","slug":"curve-output-bounds-must-be-finite-and-increasing","errorCode":null,"errorMessage":"Curve output bounds must be finite and increasing","messagePattern":"Curve output bounds must be finite and increasing","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/colorGradingCurves.ts","lineNumber":95,"sourceCode":"  let previousInput = Number.NEGATIVE_INFINITY;\n  for (const [input, output] of points) {\n    if (!Number.isFinite(input) || !Number.isFinite(output)) {\n      throw new TypeError(\"Color curve points must be finite\");\n    }\n    if (input <= previousInput) {\n      throw new RangeError(\"Color curve inputs must be strictly increasing\");\n    }\n    previousInput = input;\n  }\n}\n\nfunction validateOutputRange(\n  points: readonly HfColorCurvePoint[],\n  outputMin: number,\n  outputMax: number,\n): void {\n  if (!Number.isFinite(outputMin) || !Number.isFinite(outputMax) || outputMin >= outputMax) {\n    throw new RangeError(\"Curve output bounds must be finite and increasing\");\n  }\n  if (points.some(([, output]) => output < outputMin || output > outputMax)) {\n    throw new RangeError(`Curve outputs must be between ${outputMin} and ${outputMax}`);\n  }\n}\n\nfunction interpolateCurveSegment(\n  input: number,\n  start: HfColorCurvePoint,\n  end: HfColorCurvePoint,\n  startTangent: number,\n  endTangent: number,\n): number {\n  const span = end[0] - start[0];\n  const t = Math.min(1, Math.max(0, (input - start[0]) / span));\n  const t2 = t * t;\n  const t3 = t2 * t;\n  return (","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/colorGradingCurves.ts#L77-L113","documentation":"validateOutputRange() requires outputMin and outputMax to both be finite and strictly increasing (outputMin < outputMax). It throws a RangeError otherwise. This is used by compileHfHueCurve (hue delta bounds) and by compileCurveSamples for any curve with custom output bounds; the bounds define the clamp range and the slope scaling, so equal/infinite bounds break both.","triggerScenarios":"Calling compileHfHueCurve with outputMin >= outputMax (e.g. 0 and 0, or -1 and -2), or either bound NaN/Infinity; passing bounds in the wrong order.","commonSituations":"A hue curve with delta range derived from a slider pair where min was dragged above max; NaN from an uninitialised variable; sign confusion (expecting max,min).","solutions":["Pass outputMin < outputMax with both finite; for hue curves typical bounds are e.g. -1 and 1 (or your effect's delta range).","Normalize min/max before calling: const [lo, hi] = [Math.min(a,b), Math.max(a,b)]."],"exampleFix":"// before\nconst lut = compileHfHueCurve(pts, 1, 1); // min == max\n\n// after\nconst lut = compileHfHueCurve(pts, -1, 1); // finite, min < max","handlingStrategy":"validation","validationCode":"function validBounds(min: number, max: number): boolean {\n  return Number.isFinite(min) && Number.isFinite(max) && min < max;\n}\nif (!validBounds(outputMin, outputMax)) throw new Error('output bounds must be finite and min < max');","typeGuard":"function isValidOutputBounds(min: unknown, max: unknown): boolean {\n  return typeof min === \"number\" && typeof max === \"number\" && Number.isFinite(min) && Number.isFinite(max) && min < max;\n}","tryCatchPattern":"try { compileHfHueCurve(pts, outputMin, outputMax); }\ncatch (err) { if (/bounds must be finite and increasing/.test(String(err))) { /* fix min<max */ } else throw err; }","preventionTips":["Pass outputMin < outputMax with both finite; normalize with Math.min/Math.max before calling.","Tie UI slider order to the bounds you pass."],"tags":["color-grading","curve","validation","range","hue"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}