remotion-dev/remotion · error

Conflicting LUT input range headers.

Error message

Conflicting LUT input range headers.

What it means

A .cube file may specify its input domain either via LUT_1D_INPUT_RANGE / LUT_3D_INPUT_RANGE or via DOMAIN_MIN/DOMAIN_MAX — not both, and not mismatched 1D/3D range headers. When the parser sees an INPUT_RANGE header together with DOMAIN_MIN, DOMAIN_MAX, or the range header of the other LUT type, the intended domain is ambiguous, so it throws. This check runs after the whole file is scanned using the set of observed headers.

Solutions

  1. Delete either the INPUT_RANGE line or the DOMAIN_MIN/DOMAIN_MAX lines — keep exactly one domain specification.
  2. If both a 1D and 3D INPUT_RANGE are present, remove the one that does not match the declared LUT_*_SIZE type.
  3. Normalize the file with a converter that strips duplicate domain headers.
  4. Pre-scan headers in code and reject mixed domain specs before parsing.

Example fix

// before
LUT_3D_INPUT_RANGE 0.0 1.0
DOMAIN_MIN 0.0 0.0 0.0
DOMAIN_MAX 1.0 1.0 1.0
// after
DOMAIN_MIN 0.0 0.0 0.0
DOMAIN_MAX 1.0 1.0 1.0
Defensive patterns

Strategy: validation

Validate before calling

const headers = new Set(
  text.split(/\r?\n/)
    .map((l) => l.trim().split(/\s+/)[0])
    .filter((kw) => /^[A-Z][A-Z0-9_]*$/.test(kw)),
);
const hasRange = headers.has('LUT_1D_INPUT_RANGE') || headers.has('LUT_3D_INPUT_RANGE');
if (hasRange && (headers.has('DOMAIN_MIN') || headers.has('DOMAIN_MAX'))) {
  throw new Error('Both INPUT_RANGE and DOMAIN_* headers present');
}

Try / catch

try {
  const lut = parseCubeLut(text);
} catch (e) {
  if (/Conflicting/.test((e as Error).message)) {
    console.error('Keep exactly one domain spec: INPUT_RANGE or DOMAIN_MIN/MAX');
  }
}

Prevention

When it happens

Trigger: parseCubeLut(text) on a file containing e.g. both 'LUT_3D_INPUT_RANGE 0 1' and 'DOMAIN_MIN 0 0 0'; both 'LUT_1D_INPUT_RANGE' and 'LUT_3D_INPUT_RANGE'; or an INPUT_RANGE plus DOMAIN_MAX in the same file.

Common situations: Merging headers from two LUT files; tools that emit both the legacy INPUT_RANGE and the newer DOMAIN_* headers; hand-editing that added a domain header without removing the input-range line.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18). Data as JSON: /api/errors/3b9bff0656eebce0. Report an issue: GitHub.

Appendix: source

Thrown at packages/studio/src/helpers/cube-lut.ts:153

	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.');
	}

	return {type, size, title, domainMin, domainMax, data};
};

export const applyCubeLut = (pixels: Uint8ClampedArray, lut: CubeLut): void => {
	const {data, size, domainMin, domainMax, type} = lut;
	const last = size - 1;
	const range = domainMin.map((min, channel) => domainMax[channel] - min);

	for (let pixel = 0; pixel < pixels.length; pixel += 4) {
		if (type === '1d') {
			for (let channel = 0; channel < 3; channel++) {
				const position = Math.max(
					0,
					Math.min(
						last,
						((pixels[pixel + channel] / 255 - domainMin[channel]) /

View on GitHub (pinned to 46a3a6bf13)