remotion-dev/remotion · error
Expected LUT colors, got more.
Error message
Expected ${data.length / 3} LUT colors, got more. What it means
Once the LUT size header is known, the parser allocates a Float32Array holding exactly size*3 (1D) or size^3*3 (3D) floats, i.e. data.length/3 color entries. This error is thrown when a color line arrives after the table is already full — the file contains more color rows than the declared size allows. The message reports the exact expected count so the mismatch is obvious.
Solutions
- Correct the size header to match the actual number of color rows (e.g. set LUT_3D_SIZE 33 for 35937 rows, cube root of the data-line count).
- Remove the surplus trailing color lines.
- Re-export the LUT so the header and table agree.
- Pre-count non-header data lines in the text and compare with the declared size^3 before parsing.
Example fix
// before (8 rows of data) LUT_1D_SIZE 4 // after LUT_1D_SIZE 8
Defensive patterns
Strategy: validation
Validate before calling
const sizeMatch = /LUT_3D_SIZE\s+(\d+)/.exec(text);
if (sizeMatch) {
const n = Number(sizeMatch[1]);
const rows = text.split(/\r?\n/).filter((l) => {
const p = l.trim().split(/\s+/);
return p.length === 3 && p.every((x) => Number.isFinite(Number(x)));
}).length;
if (rows > n ** 3) throw new Error(`Header says ${n ** 3} colors, file has ${rows}`);
} Try / catch
try {
const lut = parseCubeLut(text);
} catch (e) {
if (/got more/.test((e as Error).message)) {
console.error('Declared LUT size is smaller than the color table');
}
} Prevention
- Never edit LUT_*_SIZE without regenerating the color table
- Count data lines and verify size^3 matches before shipping a LUT
- Keep the size header and table from the same export
When it happens
Trigger: parseCubeLut(text) where the declared LUT_3D_SIZE n implies n^3 colors but the file contains more than n^3 data lines (e.g. declared 32 while the table has 33^3 entries), or a 1D LUT declared with LUT_1D_SIZE smaller than its actual table length.
Common situations: Size header edited after export (author shrank LUT_3D_SIZE to save space but kept the full table); files exported at one resolution and patched to another; truncated re-save that kept the old (larger) table but lowered the header value.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Combined 1D and 3D LUTs are not supported.
- Duplicate on line .
- Expected LUT colors, got .
- Expected LUT_1D_SIZE or LUT_3D_SIZE.
- Expected LUT_1D_SIZE or LUT_3D_SIZE before color data.
AI-assisted analysis of remotion-dev/remotion@46a3a6bf13 (2026-09-18).
Data as JSON: /api/errors/92c1f374e8ff3cd4.
Report an issue: GitHub.
Appendix: source
Thrown at packages/studio/src/helpers/cube-lut.ts:118
throw new Error(
`Unsupported LUT header "${keyword}" on line ${index + 1}.`,
);
}
if (data === null) {
throw new Error('Expected LUT_1D_SIZE or LUT_3D_SIZE before color data.');
}
const color = [Number(keyword), ...numbers];
if (
color.length !== 3 ||
!color.every((value) => Number.isFinite(Math.fround(value)))
) {
throw new Error(`Invalid LUT color on line ${index + 1}.`);
}
if (offset + 3 > data.length) {
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(View on GitHub (pinned to 46a3a6bf13)