heygen-com/hyperframes · error · CubeLutParseError
LUT data rows must contain three numbers
Error message
LUT data rows must contain three numbers
What it means
Each 3D LUT data row must carry exactly three numeric tokens (R, G, B). The throw at line 163 fires when a numeric data line splits into a token count other than three. It runs after LUT_3D_SIZE is known, so it only applies to genuine data rows.
Source
Thrown at packages/core/src/colorLuts.ts:163
throw new CubeLutParseError(`LUT_3D_SIZE ${lut3dSize} exceeds max ${maxSize}`, lineNumber);
}
continue;
}
if (!isNumericDataLine(keyword)) {
if (keyword.startsWith("LUT_")) {
throw new CubeLutParseError(`Unsupported cube keyword ${keyword}`, lineNumber);
}
continue;
}
if (!lut3dSize) {
if (lut1dSize) {
throw new CubeLutParseError("1D cube LUTs are not supported yet", lineNumber);
}
throw new CubeLutParseError("LUT data appears before LUT_3D_SIZE", lineNumber);
}
if (parts.length !== 3) {
throw new CubeLutParseError("LUT data rows must contain three numbers", lineNumber);
}
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;View on GitHub (pinned to c2996c8626)
Solutions
- Ensure every data row has exactly three numeric values separated by whitespace.
- If the source is RGBA, drop the fourth column before parsing.
- Normalize repeated whitespace (e.g. text.replace(/\s+/g, ' ')) and re-check.
Example fix
// before 0.10 0.20 0.30 1.00 // after 0.10 0.20 0.30
Defensive patterns
Strategy: try-catch
Validate before calling
function assertDataRowsAreTriples(fileText: string): void {
for (const line of fileText.split(/\r?\n/)) {
const tok = line.trim().split(/\s+/)[0] ?? '';
if (/^[+-]?(?:\d|\.\d)/.test(tok) && line.trim().split(/\s+/).length !== 3) {
throw new Error('Each data row must have exactly three numbers');
}
}
} Try / catch
try {
parseCubeLut(fileText);
} catch (err) {
if (err instanceof CubeLutParseError && /must contain three numbers/.test(err.message)) {
// report err.lineNumber; if RGBA, strip the 4th column and retry
} else throw err;
} Prevention
- Export RGB (3 channels), not RGBA, from the source tool.
- Normalize repeated whitespace before parsing.
- Validate row arity in a pre-scan when ingesting untrusted LUTs.
When it happens
Trigger: A row like '0.1 0.2' (two channels), '0.1 0.2 0.3 0.4' (four — e.g. RGBA), or a row where a stray whitespace token inflated the count.
Common situations: RGBA exports from a tool that appends alpha; a missing channel from a truncated row; an extra blank-ish token (tab sequences) producing an empty string in the split.
Related errors
- Invalid number "${value}"
- ${keyword} expects three numbers
- ${keyword} expects a size
- ${keyword} must be an integer greater than 1
- DOMAIN_MAX values must be greater than DOMAIN_MIN values
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/5e76a2c836623977.
Report an issue: GitHub.