heygen-com/hyperframes · error · CubeLutParseError

Missing LUT_3D_SIZE

Error message

Missing LUT_3D_SIZE

What it means

Thrown by parseCubeLut after scanning the entire .cube file: no LUT_3D_SIZE (and no LUT_1D_SIZE) keyword was ever seen. The Adobe .cube spec requires a LUT_3D_SIZE header before the data table; without it the row count and packing are undefined, so the parser refuses to guess. Note this is distinct from the line-accurate 'LUT data appears before LUT_3D_SIZE' (colorLuts.ts:160) — reaching line 177 means no numeric data rows were recognised either, i.e. the file is structurally incomplete (only TITLE/DOMAIN lines, or unrecognised content).

Source

Thrown at packages/core/src/colorLuts.ts:177

      }
      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;
  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),
  };
}

View on GitHub (pinned to c2996c8626)

Solutions

  1. Open the .cube file and confirm a line reads exactly 'LUT_3D_SIZE N' (N integer >= 2) appears before any numeric data rows.
  2. If the file is a 1D LUT, note that this parser only supports 3D LUTs — convert it to a 3D .cube or use a different loader.
  3. Check for keyword typos: the parser uppercases token[0] and compares to the literal 'LUT_3D_SIZE' (no colon, no underscores moved).
  4. If the file came from a download/export, re-export it from the source tool (DaVinci Resolve, Photoshop, etc.) — truncation is the usual cause.

Example fix

// before — header line malformed, keyword never matches
TITLE "my lut"
LUT3D_SIZE 17
0.0 0.0 0.0
...

// after — exact keyword
TITLE "my lut"
LUT_3D_SIZE 17
0.0 0.0 0.0
...
Defensive patterns

Strategy: validation

Validate before calling

// Pre-validate a .cube file before calling parseCubeLut
import { readFileSync } from 'node:fs';
export function assertCubeHasSize(path: string): void {
  const text = readFileSync(path, 'utf-8');
  const has3d = /^LUT_3D_SIZE\s+\d+/im.test(text);
  const has1d = /^LUT_1D_SIZE\s+\d+/im.test(text);
  if (!has3d && !has1d) {
    throw new Error(`${path} has no LUT_3D_SIZE / LUT_1D_SIZE header`);
  }
}

Try / catch

import { parseCubeLut, CubeLutParseError } from '.../colorLuts';
try {
  const lut = parseCubeLut(text);
} catch (err) {
  if (err instanceof CubeLutParseError && /Missing LUT_3D_SIZE/.test(err.message)) {
    // surface a 're-export the .cube with a size header' message to the user
  } else throw err;
}

Prevention

When it happens

Trigger: Calling parseCubeLut on a file that contains only a TITLE line; a file with comments/header metadata but the LUT_3D_SIZE line deleted; a file where the size line was misspelled (e.g. 'LUT3D_SIZE' or 'LUT_3D_SIZE:') so the keyword match at colorLuts.ts:142 fails and the line falls through to the generic skip at line 154; passing an empty or whitespace-only string.

Common situations: Truncation during download or copy-paste of a .cube file losing the trailing header; hand-authored LUT files with a typo in the keyword; feeding a 1D .cube snippet that never declared LUT_1D_SIZE; reading the wrong file (e.g. a .png or a .txt readme) whose path was mistakenly passed to parseCubeLut.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/ff8409d71b6b9ec4. Report an issue: GitHub.