heygen-com/hyperframes · error · CubeLutParseError

LUT data appears before LUT_3D_SIZE

Error message

LUT data appears before LUT_3D_SIZE

What it means

Numeric data rows must appear after the LUT_3D_SIZE header so the parser knows how many rows to expect. The throw at line 160 fires when a numeric token is the first item on a line, lut3dSize is still null, and no LUT_1D_SIZE was set either. The reported lineNumber points at the premature data row.

Source

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

    if (keyword === "LUT_3D_SIZE") {
      lut3dSize = parseSize(rest[0], keyword, lineNumber);
      if (lut3dSize > maxSize) {
        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");
  }

View on GitHub (pinned to c2996c8626)

Solutions

  1. Move the 'LUT_3D_SIZE N' line (and optional TITLE/DOMAIN_*) above the first data row.
  2. Re-export the LUT — well-formed .cube files always emit the header first.
  3. If building LUTs programmatically, write headers before data in your serializer.

Example fix

// before
0.0 0.0 0.0
1.0 1.0 1.0
LUT_3D_SIZE 2

// after
LUT_3D_SIZE 2
0.0 0.0 0.0
1.0 1.0 1.0
Defensive patterns

Strategy: try-catch

Validate before calling

function assertSizeBeforeData(fileText: string): void {
  const lines = fileText.split(/\r?\n/);
  let sawSize = false;
  for (const line of lines) {
    const tok = line.trim().split(/\s+/)[0] ?? '';
    if ((tok as string).toUpperCase() === 'LUT_3D_SIZE') sawSize = true;
    else if (/^[+-]?(?:\d|\.\d)/.test(tok) && !sawSize) {
      throw new Error('Numeric data appears before LUT_3D_SIZE');
    }
  }
}

Try / catch

try {
  parseCubeLut(fileText);
} catch (err) {
  if (err instanceof CubeLutParseError && /appears before LUT_3D_SIZE/.test(err.message)) {
    // move/re-insert the LUT_3D_SIZE header above the data, then retry
  } else throw err;
}

Prevention

When it happens

Trigger: A file whose data rows precede the 'LUT_3D_SIZE N' header line — e.g. a reordered file, or a header that was stripped and only data remains.

Common situations: Manual reordering of a .cube file; a partially-written file where the header was lost; concatenation that put data before metadata.

Related errors


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