{"record":{"id":"1acd585c5d804999","repo":"heygen-com/hyperframes","slug":"curve-lut-size-must-be-at-least-2","errorCode":null,"errorMessage":"Curve LUT size must be at least 2","messagePattern":"Curve LUT size must be at least 2","errorType":"validation","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/colorGradingCurves.ts","lineNumber":75,"sourceCode":"    const before = valueAt(slopes, index - 1);\n    const after = valueAt(slopes, index);\n    if (before === 0 || after === 0 || Math.sign(before) !== Math.sign(after)) {\n      result[index] = 0;\n      continue;\n    }\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 {","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/core/src/colorGradingCurves.ts#L57-L93","documentation":"validateCurvePoints() rejects a LUT `size` that is not an integer or is less than 2. Size is the number of samples the curve is compiled into (the Float32Array length). A non-integer or sub-2 size makes sampling mathematically invalid (index/(size-1) divides by zero or produces fractional indices).","triggerScenarios":"Calling compileHfColorCurve(points, 1), compileHfColorCurve(points, 0), compileHfColorCurve(points, 1.5), compileHfColorCurve(points, NaN), or compileHfColorCurve(points, -4) as the second argument. The default HF_COLOR_CURVE_LUT_SIZE (1024) avoids this.","commonSituations":"Passing a custom small size for testing; computing size from a variable that went NaN or got truncated; misusing the API by passing the number of points as the second arg.","solutions":["Omit the size argument to use the default HF_COLOR_CURVE_LUT_SIZE (1024).","If supplying a custom size, ensure it is an integer >= 2 (and typically a power of two for GPU textures)."],"exampleFix":"// before\nconst lut = compileHfColorCurve(pts, 1); // size < 2\n\n// after\nconst lut = compileHfColorCurve(pts); // default 1024\n// or an explicit valid size\nconst lut = compileHfColorCurve(pts, 256);","handlingStrategy":"validation","validationCode":"function validLutSize(n: number): boolean { return Number.isInteger(n) && n >= 2; }\nconst size = opts.size && validLutSize(opts.size) ? opts.size : HF_COLOR_CURVE_LUT_SIZE;","typeGuard":"function isValidLutSize(n: unknown): n is number {\n  return typeof n === \"number\" && Number.isInteger(n) && n >= 2;\n}","tryCatchPattern":"try { compileHfColorCurve(pts, size); }\ncatch (err) { if (/LUT size/.test(String(err))) { compileHfColorCurve(pts); } else throw err; }","preventionTips":["Omit the size argument to use the safe default (1024).","Validate size is an integer >= 2 before passing."],"tags":["color-grading","curve","validation","range","lut"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}