heygen-com/hyperframes · error · CubeLutParseError
Expected ${expectedRows} LUT rows for size ${lut3dSize}, fou
Error message
Expected ${expectedRows} LUT rows for size ${lut3dSize}, found ${rows.length / 3} What it means
After parsing, the row count must equal LUT_3D_SIZE^3 RGB triples. The check at line 182-185 rejects a mismatch between declared size and actual data volume. The message reports both the expected count and the count found (rows.length / 3). Note this throw has no lineNumber — it is a whole-file summary error.
Source
Thrown at packages/core/src/colorLuts.ts:183
rows.push(
parseFiniteNumber(parts[0]!, lineNumber),
parseFiniteNumber(parts[1]!, lineNumber),
parseFiniteNumber(parts[2]!, lineNumber),
);
}
if (lut1dSize && lut3dSize) {
throw new CubeLutParseError("Mixed 1D and 3D cube LUTs are not supported yet");
}
if (!lut3dSize) {
if (lut1dSize) throw new CubeLutParseError("1D cube LUTs are not supported yet");
throw new CubeLutParseError("Missing LUT_3D_SIZE");
}
validateDomain(domainMin, domainMax);
const expectedRows = lut3dSize * lut3dSize * lut3dSize;
if (rows.length !== expectedRows * 3) {
throw new CubeLutParseError(
`Expected ${expectedRows} LUT rows for size ${lut3dSize}, found ${rows.length / 3}`,
);
}
return {
title,
size: lut3dSize,
domainMin,
domainMax,
data: new Float32Array(rows),
};
}
function clampUnit(value: number): number {
if (!Number.isFinite(value)) return 0;
return Math.min(1, Math.max(0, value));
}
View on GitHub (pinned to c2996c8626)
Solutions
- Compare the message's expected vs found counts; if found < expected, the file is truncated — re-download/re-export.
- If found > expected, remove duplicate rows or raise LUT_3D_SIZE to match the body.
- If the size header is wrong, correct it to cube-root of (row count), e.g. size = Math.cbrt(rows.length).
- Validate before parsing: count numeric triples and assert === size*size*size.
Example fix
// before — header says size 4 (expects 64 rows) but only 27 present LUT_3D_SIZE 4 ... 27 rows ... // after — match size to body (cube root of 27 is 3) LUT_3D_SIZE 3 ... 27 rows ...
Defensive patterns
Strategy: validation
Validate before calling
function expectedRowCount(fileText: string): number | null {
const m = /^LUT_3D_SIZE\s+(\d+)/m.exec(fileText);
if (!m) return null;
const n = Number(m[1]);
return n * n * n;
}
function actualRowCount(fileText: string): number {
return fileText.split(/\r?\n/).filter((l) => {
const t = l.trim().split(/\s+/);
return t.length === 3 && /^[+-]?(?:\d|\.\d)/.test(t[0] ?? '');
}).length;
}
const expected = expectedRowCount(fileText);
if (expected !== null && actualRowCount(fileText) !== expected) {
throw new Error(`Row count mismatch: expected ${expected}`);
} Try / catch
try {
parseCubeLut(fileText);
} catch (err) {
if (err instanceof CubeLutParseError && /Expected .* LUT rows/.test(err.message)) {
// parse expected vs found from the message; either re-export, drop duplicates, or fix LUT_3D_SIZE
} else throw err;
} Prevention
- Validate that numeric row count === size^3 before parsing.
- Re-export truncated LUTs from the source tool rather than patching.
- When generating LUTs, assert data length === size*size*size*3 at serialization time.
When it happens
Trigger: Declaring 'LUT_3D_SIZE 4' but providing fewer or more than 64 rows (4^3 = 64); truncating or duplicating data rows; declaring the wrong size for the body.
Common situations: Truncated download; an extra blank line that the parser skipped causing an off-by-one in row count; declaring size 33 but supplying a size-32 body (32768 vs 35937 rows); copy-paste duplicating a block.
Related errors
- LUT data rows must contain three numbers
- Invalid number "${value}"
- ${keyword} expects three numbers
- ${keyword} expects a size
- ${keyword} must be an integer greater than 1
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/2d3b5466a5ecef75.
Report an issue: GitHub.