{"record":{"id":"0a572e6eabedacf4","repo":"remotion-dev/remotion","slug":"domain-max-must-be-greater-than-domain-min-in-every-channel","errorCode":null,"errorMessage":"DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.","messagePattern":"DOMAIN_MAX must be greater than DOMAIN_MIN in every channel\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/studio/src/helpers/cube-lut.ts","lineNumber":136,"sourceCode":"\t\t\tthrow new Error(`Expected ${data.length / 3} LUT colors, got more.`);\n\t\t}\n\n\t\tdata.set(color, offset);\n\t\toffset += 3;\n\t}\n\n\tif (type === null || data === null) {\n\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}","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/remotion-dev/remotion/blob/46a3a6bf13ca367376ff18bbb06dae2e87e0d068/packages/studio/src/helpers/cube-lut.ts#L118-L154","documentation":"The LUT input domain (from DOMAIN_MIN/DOMAIN_MAX headers or INPUT_RANGE) must be a valid box: in every RGB channel the max must be strictly greater than the min, otherwise the range (domainMax - domainMin) used to normalize pixel values in applyCubeLut would be zero or negative and the lookup would collapse or invert. parseCubeLut throws this after the table is fully read if any channel has min >= max.","triggerScenarios":"parseCubeLut(text) with headers like 'DOMAIN_MIN 0 0 0' plus 'DOMAIN_MAX 1 1 0' (third channel max == min), 'DOMAIN_MAX 0 0 0' (degenerate), or an INPUT_RANGE line already rejected by error 70 that instead arrives via DOMAIN_MIN/MAX, e.g. 'DOMAIN_MIN 1 1 1' with default DOMAIN_MAX [1,1,1].","commonSituations":"Hand-edited domain headers; LUTs authored for a single-channel domain mistakenly written per-channel with equal values; header lines partially deleted leaving min >= remaining default max.","solutions":["Set DOMAIN_MAX strictly greater than DOMAIN_MIN in all three channels (e.g. 'DOMAIN_MIN 0 0 0' / 'DOMAIN_MAX 1 1 1').","Remove DOMAIN_MIN/DOMAIN_MAX headers to use the default [0,1] domain.","If the LUT truly has a zero-width channel, the file is invalid — regenerate it.","Pre-check parsed domains in code before applying the LUT to frames."],"exampleFix":"// before\nDOMAIN_MIN 0 0 0\nDOMAIN_MAX 1 1 0\n// after\nDOMAIN_MIN 0 0 0\nDOMAIN_MAX 1 1 1","handlingStrategy":"validation","validationCode":"const isStrictlyIncreasing = (min: number[], max: number[]): boolean =>\n  min.length === 3 && max.length === 3 && max.every((m, i) => m > min[i]);","typeGuard":null,"tryCatchPattern":"try {\n  const lut = parseCubeLut(text);\n} catch (e) {\n  if (/DOMAIN_MAX/.test((e as Error).message)) {\n    console.error('LUT domain is degenerate in at least one channel');\n  }\n}","preventionTips":["Ensure DOMAIN_MAX > DOMAIN_MIN in all three channels","Drop DOMAIN_* headers to accept the default [0,1] domain","Treat zero-width channel domains as authoring bugs and regenerate the LUT"],"tags":["lut","validation","color"],"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"}