{"record":{"id":"57a12b0b7fd67316","repo":"remotion-dev/remotion","slug":"lut-input-ranges-must-be-finite","errorCode":null,"errorMessage":"LUT input ranges must be finite.","messagePattern":"LUT input ranges must be finite\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio/src/helpers/cube-lut.ts","lineNumber":144,"sourceCode":"\t\tthrow new Error('Expected LUT_1D_SIZE or LUT_3D_SIZE.');\n\t}\n\n\tif (offset !== data.length) {\n\t\tthrow new Error(\n\t\t\t`Expected ${data.length / 3} LUT colors, got ${offset / 3}.`,\n\t\t);\n\t}\n\n\tif (domainMin.some((min, channel) => min >= domainMax[channel])) {\n\t\tthrow new Error(\n\t\t\t'DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.',\n\t\t);\n\t}\n\n\tif (\n\t\tdomainMin.some((min, channel) => !Number.isFinite(domainMax[channel] - min))\n\t) {\n\t\tthrow new Error('LUT input ranges must be finite.');\n\t}\n\n\tif (\n\t\t(headers.has('LUT_1D_INPUT_RANGE') || headers.has('LUT_3D_INPUT_RANGE')) &&\n\t\t(headers.has('DOMAIN_MIN') ||\n\t\t\theaders.has('DOMAIN_MAX') ||\n\t\t\theaders.has(type === '1d' ? 'LUT_3D_INPUT_RANGE' : 'LUT_1D_INPUT_RANGE'))\n\t) {\n\t\tthrow new Error('Conflicting LUT input range headers.');\n\t}\n\n\treturn {type, size, title, domainMin, domainMax, data};\n};\n\nexport const applyCubeLut = (pixels: Uint8ClampedArray, lut: CubeLut): void => {\n\tconst {data, size, domainMin, domainMax, type} = lut;\n\tconst last = size - 1;\n\tconst range = domainMin.map((min, channel) => domainMax[channel] - min);","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/helpers/cube-lut.ts#L126-L162","documentation":"Even when max > min per channel, the parser additionally requires each channel's range (domainMax[channel] - domainMin[channel]) to be finite — guarding against Infinity or -Infinity bound values whose difference is NaN (Infinity - Infinity) or Infinity. Such domains would produce NaN lookup positions in applyCubeLut and corrupt every pixel. The default domain is [0,0,0]-[1,1,1], so this only fires when custom headers introduce non-finite bounds.","triggerScenarios":"parseCubeLut(text) where DOMAIN_MIN and DOMAIN_MAX both use Infinity (difference NaN), e.g. 'DOMAIN_MIN -Infinity -Infinity -Infinity' with 'DOMAIN_MAX Infinity Infinity Infinity', or a DOMAIN header pairing ±Infinity values.","commonSituations":"Generated LUT files that serialized unbounded domains as Infinity instead of large finite numbers; JSON-to-cube converters passing through Infinity; mathematically 'unbounded' LUT ideas written literally.","solutions":["Replace Infinity bounds with large finite values (e.g. -1000 and 1000).","Clamp the domain to the realistic input range, typically 'DOMAIN_MIN 0 0 0' / 'DOMAIN_MAX 1 1 1'.","Fix the generator/converter to emit finite numbers only.","Filter the text: reject lines containing Infinity/NaN before calling parseCubeLut."],"exampleFix":"// before\nDOMAIN_MIN -Infinity -Infinity -Infinity\nDOMAIN_MAX Infinity Infinity Infinity\n// after\nDOMAIN_MIN 0 0 0\nDOMAIN_MAX 1 1 1","handlingStrategy":"validation","validationCode":"if (/\\b(Infinity|NaN)\\b/.test(text)) {\n  throw new Error('LUT contains non-finite numbers');\n}","typeGuard":"const hasFiniteDomain = (min: number[], max: number[]): boolean =>\n  min.every(Number.isFinite) && max.every(Number.isFinite) &&\n  min.every((m, i) => Number.isFinite(max[i] - m));","tryCatchPattern":"try {\n  const lut = parseCubeLut(text);\n} catch (e) {\n  if (/must be finite/.test((e as Error).message)) {\n    console.error('LUT domain uses Infinity — clamp to a finite range');\n  }\n}","preventionTips":["Never serialize Infinity into .cube headers; use large finite bounds","Fix generators/converters to emit finite numbers only","Scan LUT text for Infinity/NaN before applying"],"tags":["lut","validation","numbers"],"backgroundTag":"invalid-config-value","analyzedSha":"46a3a6bf13ca367376ff18bbb06dae2e87e0d068","analyzedAt":"2026-09-18T00:12:20.256Z","contentChangedAt":"2026-09-18T00:12:20.256Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}