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

  1. Compare the message's expected vs found counts; if found < expected, the file is truncated — re-download/re-export.
  2. If found > expected, remove duplicate rows or raise LUT_3D_SIZE to match the body.
  3. If the size header is wrong, correct it to cube-root of (row count), e.g. size = Math.cbrt(rows.length).
  4. 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

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


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