remotion-dev/remotion · error
DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.
Error message
DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.
What it means
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.
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.
Example fix
// before DOMAIN_MIN 0 0 0 DOMAIN_MAX 1 1 0 // after DOMAIN_MIN 0 0 0 DOMAIN_MAX 1 1 1
Defensive patterns
Strategy: validation
Validate before calling
const isStrictlyIncreasing = (min: number[], max: number[]): boolean => min.length === 3 && max.length === 3 && max.every((m, i) => m > min[i]);
Try / catch
try {
const lut = parseCubeLut(text);
} catch (e) {
if (/DOMAIN_MAX/.test((e as Error).message)) {
console.error('LUT domain is degenerate in at least one channel');
}
} Prevention
- 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
When it happens
Trigger: 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].
Common situations: 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.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- "backgroundColor" must be a string
- "colorA" must be a string
- "colorB" must be a string
- Combined 1D and 3D LUTs are not supported.
- Conflicting LUT input range headers.
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/0a572e6eabedacf4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio/src/helpers/cube-lut.ts:136
throw new Error(`Expected ${data.length / 3} LUT colors, got more.`);
}
data.set(color, offset);
offset += 3;
}
if (type === null || data === null) {
throw new Error('Expected LUT_1D_SIZE or LUT_3D_SIZE.');
}
if (offset !== data.length) {
throw new Error(
`Expected ${data.length / 3} LUT colors, got ${offset / 3}.`,
);
}
if (domainMin.some((min, channel) => min >= domainMax[channel])) {
throw new Error(
'DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.',
);
}
if (
domainMin.some((min, channel) => !Number.isFinite(domainMax[channel] - min))
) {
throw new Error('LUT input ranges must be finite.');
}
if (
(headers.has('LUT_1D_INPUT_RANGE') || headers.has('LUT_3D_INPUT_RANGE')) &&
(headers.has('DOMAIN_MIN') ||
headers.has('DOMAIN_MAX') ||
headers.has(type === '1d' ? 'LUT_3D_INPUT_RANGE' : 'LUT_1D_INPUT_RANGE'))
) {
throw new Error('Conflicting LUT input range headers.');
}View on GitHub (pinned to 46a3a6bf13)