remotion-dev/remotion · error · TypeError
Invalid LUT content on line
Error message
Invalid LUT content on line ${lineNumber}: LUT_3D_SIZE must be declared before the color data What it means
This TypeError enforces ordering in .cube LUT files: the parser must know the LUT_3D_SIZE grid dimension before it can interpret or count color rows, since the row count and triplet layout depend on it. Within parseCubeLut, `size` starts as null and is only set when the LUT_3D_SIZE header line is parsed; if a color-data row (a line whose first token is numeric, not an uppercase directive) arrives while size is still null, the file lacks the required header before its data section. It signals a malformed .cube file, so the fix is to add the LUT_3D_SIZE declaration above the color rows.
Solutions
- Add a LUT_3D_SIZE declaration before the first color row with the correct grid dimension
- Verify the row count equals size^3 after adding the header
- Re-export the LUT so the header is included
Example fix
// before 0 0 0 0 0 1 // after LUT_3D_SIZE 2 0 0 0 0 0 1
Defensive patterns
Strategy: validation
Validate before calling
const firstNonEmpty = content.split(/\r?\n/).map((l) => l.split('#')[0].trim()).find((l) => l.length > 0);
if (firstNonEmpty && /^\d/.test(firstNonEmpty)) throw new Error('File starts with color data: LUT_3D_SIZE missing'); Type guard
null
Try / catch
try {
const lut = parseCubeLut(content);
} catch (e) {
if (e instanceof TypeError && e.message.includes('must be declared before the color data')) {
// insert the LUT_3D_SIZE header or reject the malformed file
} else throw e;
} Prevention
- Never strip headers when preprocessing LUT files
- Validate that the first non-empty, non-comment line is a header directive
When it happens
Trigger: A .cube file starts directly with color rows like '0 0 0' without a preceding 'LUT_3D_SIZE N' line passed to parseCubeLut().
Common situations: Header stripped by an editor or script, files truncated at the top, or data generated without emitting the size header.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- Combined 1D and 3D LUTs are not supported.
- Conflicting LUT input range headers.
- DOMAIN_MAX must be greater than DOMAIN_MIN in every channel.
- Duplicate on line .
- Expected LUT colors, got more.
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/0fb8b2e55d875261.
Report an issue: GitHub.
Appendix: source
Thrown at packages/effects/src/lut/parse-cube-lut.ts:165
}
domainMax = parseTriplet({
values,
lineNumber,
label: 'DOMAIN_MAX',
});
hasDomainMax = true;
continue;
}
if (/^[A-Z_]/i.test(keyword)) {
throw new TypeError(
`Invalid LUT content on line ${lineNumber}: unsupported directive "${keyword}"`,
);
}
if (size === null) {
throw new TypeError(
`Invalid LUT content on line ${lineNumber}: LUT_3D_SIZE must be declared before the color data`,
);
}
parseTriplet({
values: [keyword, ...values],
lineNumber,
label: 'color row',
});
dataStarted = true;
dataRows++;
const maxDataRows = size ** 3;
if (dataRows > maxDataRows) {
throw new TypeError(
`Invalid LUT content: expected ${maxDataRows} color rows for LUT_3D_SIZE ${size}, but got more`,
);
}View on GitHub (pinned to 46a3a6bf13)