remotion-dev/remotion · error · TypeError

Invalid LUT content on line

Error message

Invalid LUT content on line ${lineNumber}: ${keyword} must appear before the color data

What it means

parseCubeLut() parses .cube LUT files and requires all header directives (TITLE, LUT_3D_SIZE, DOMAIN_MIN, DOMAIN_MAX) to appear before any color data rows. If a header directive is encountered after the first color row, this TypeError is thrown because re-ordering or mixing headers into the data section is invalid per the .cube format.

Solutions

  1. Move all header directives (TITLE, LUT_3D_SIZE, DOMAIN_MIN, DOMAIN_MAX) to the top of the .cube file before any color rows
  2. Regenerate or re-export the LUT from the original tool with correct header ordering
  3. Check the line number in the message and inspect that line for a misplaced header keyword

Example fix

// before
0 0 0
LUT_3D_SIZE 2
0 0 1
// after
LUT_3D_SIZE 2
0 0 0
0 0 1
Defensive patterns

Strategy: validation

Validate before calling

const validateHeaderOrder = (content: string) => {
  let dataStarted = false;
  for (const line of content.split(/\r?\n/)) {
    const trimmed = line.split('#')[0].trim();
    if (!trimmed) continue;
    if (/^\d/.test(trimmed)) { dataStarted = true; continue; }
    if (dataStarted && /^(TITLE|LUT_3D_SIZE|DOMAIN_MIN|DOMAIN_MAX)\b/.test(trimmed)) {
      throw new Error(`Header directive after data: ${trimmed}`);
    }
  }
};

Type guard

null

Try / catch

try {
  const lut = parseCubeLut(content);
} catch (e) {
  if (e instanceof TypeError && e.message.includes('must appear before the color data')) {
    // re-order headers or surface a user-friendly LUT error
  } else throw e;
}

Prevention

When it happens

Trigger: A .cube file passed to parseCubeLut() has a header line like TITLE or LUT_3D_SIZE or DOMAIN_MIN/MAX placed after at least one numeric color row, e.g. colors pasted before the size declaration or an appended header at the end of the file.

Common situations: Hand-edited LUT files, files concatenated in the wrong order, generators that emit data before headers, or tools that append metadata at the bottom of the file.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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

Appendix: source

Thrown at packages/effects/src/lut/parse-cube-lut.ts:83

	for (let index = 0; index < lines.length; index++) {
		const lineNumber = index + 1;
		const line = stripComment(lines[index]).trim();
		if (line.length === 0) {
			continue;
		}

		const [keyword, ...values] = line.split(/\s+/);

		if (keyword === 'LUT_1D_SIZE') {
			throw new TypeError(
				`Invalid LUT content on line ${lineNumber}: 1D LUTs are not supported`,
			);
		}

		if (HEADER_DIRECTIVES.has(keyword)) {
			if (dataStarted) {
				throw new TypeError(
					`Invalid LUT content on line ${lineNumber}: ${keyword} must appear before the color data`,
				);
			}

			if (keyword === 'TITLE') {
				if (hasTitle) {
					throw new TypeError(
						`Invalid LUT content on line ${lineNumber}: TITLE may only be declared once`,
					);
				}

				hasTitle = true;
				continue;
			}

			if (keyword === 'LUT_3D_SIZE') {
				if (size !== null) {
					throw new TypeError(

View on GitHub (pinned to 46a3a6bf13)