{"record":{"id":"1a3e423104277885","repo":"heygen-com/hyperframes","slug":"color-curve-points-must-be-finite","errorCode":null,"errorMessage":"Color curve points must be finite","messagePattern":"Color curve points must be finite","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/colorGradingCurves.ts","lineNumber":80,"sourceCode":"    }\n    const beforeSpan = valueAt(spans, index - 1);\n    const afterSpan = valueAt(spans, index);\n    const beforeWeight = 2 * afterSpan + beforeSpan;\n    const afterWeight = afterSpan + 2 * beforeSpan;\n    result[index] = (beforeWeight + afterWeight) / (beforeWeight / before + afterWeight / after);\n  }\n  return result;\n}\n\nfunction validateCurvePoints(points: readonly HfColorCurvePoint[], size: number): void {\n  if (points.length < 2) throw new RangeError(\"A color curve requires at least two points\");\n  if (!Number.isInteger(size) || size < 2) {\n    throw new RangeError(\"Curve LUT size must be at least 2\");\n  }\n  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}`);","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/colorGradingCurves.ts#L62-L98","documentation":"validateCurvePoints() iterates every point and rejects any whose input or output is not finite (NaN, +Infinity, -Infinity) as a TypeError. Non-finite values poison the cubic interpolation math (tangents become NaN, the whole LUT is corrupted), so they must be caught at the boundary. Number.isFinite excludes Infinity unlike plain truthiness.","triggerScenarios":"A point produced by division by zero or a failed parseFloat (NaN); Infinity coming from an unbounded UI slider; a deserialized value that was 'null' coerced to 0 then divided; floating point overflow.","commonSituations":"UI input parsed with Number('') yielding 0 then used in 1/x; a JSON value of null coerced to NaN; sliders with no clamp producing Infinity at extremes; bad math in a curve-editing tool.","solutions":["Clamp/sanitize every point coordinate with Number.isFinite before constructing the points array, replacing non-finite values with a sensible default.","Validate UI slider ranges and parse inputs defensively."],"exampleFix":"// before\nconst pts = [[0, 0], [0.5, NaN], [1, 1]];\ncompileHfColorCurve(pts); // throws Color curve points must be finite\n\n// after\nconst clean = pts.map(([i, o]) => [i, Number.isFinite(o) ? o : 0.5] as const);\ncompileHfColorCurve(clean);","handlingStrategy":"validation","validationCode":"const clean = points.filter(([i, o]) => Number.isFinite(i) && Number.isFinite(o));\nif (clean.length !== points.length) throw new Error('curve has non-finite points');","typeGuard":"function allFinite(points: readonly (readonly [number, number])[]): boolean {\n  return points.every(([i, o]) => Number.isFinite(i) && Number.isFinite(o));\n}","tryCatchPattern":"try { compileHfColorCurve(pts); }\ncatch (err) { if (/must be finite/.test(String(err))) { pts = pts.map(([i,o]) => [i, Number.isFinite(o)?o:0.5] as const); } else throw err; }","preventionTips":["Sanitize all slider/parse output with Number.isFinite before building points.","Coerce NaN/Infinity to a sensible default rather than passing through."],"tags":["color-grading","curve","validation","nan","type"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}