heygen-com/hyperframes · error · CubeLutParseError

${keyword} must be an integer greater than 1

Error message

${keyword} must be an integer greater than 1

What it means

After confirming a size token exists, parseSize verifies it is an integer >= 2. A 3D LUT of size 1 is a single texel (degenerate, no interpolation), and a fractional size has no physical meaning, so both are rejected at line 67-68.

Source

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

  return parsed;
}

function parseVec3(parts: string[], keyword: string, lineNumber: number): CubeLutVec3 {
  if (parts.length !== 3) {
    throw new CubeLutParseError(`${keyword} expects three numbers`, lineNumber);
  }
  return [
    parseFiniteNumber(parts[0]!, lineNumber),
    parseFiniteNumber(parts[1]!, lineNumber),
    parseFiniteNumber(parts[2]!, lineNumber),
  ];
}

function parseSize(value: string | undefined, keyword: string, lineNumber: number): number {
  if (!value) throw new CubeLutParseError(`${keyword} expects a size`, lineNumber);
  const parsed = Number(value);
  if (!Number.isInteger(parsed) || parsed < 2) {
    throw new CubeLutParseError(`${keyword} must be an integer greater than 1`, lineNumber);
  }
  return parsed;
}

function validateDomain(domainMin: CubeLutVec3, domainMax: CubeLutVec3): void {
  if (
    domainMax[0] <= domainMin[0] ||
    domainMax[1] <= domainMin[1] ||
    domainMax[2] <= domainMin[2]
  ) {
    throw new CubeLutParseError("DOMAIN_MAX values must be greater than DOMAIN_MIN values");
  }
}

function parseTitle(line: string): string | null {
  const quoted = /^TITLE\s+"([^"]*)"\s*$/i.exec(line);
  if (quoted) return quoted[1] ?? null;
  const bare = /^TITLE\s+(.+)\s*$/i.exec(line);

View on GitHub (pinned to c2996c8626)

Solutions

  1. Use an integer >= 2 (typical values: 17, 25, 32, 33, 64).
  2. Round any computed size to the nearest integer and clamp to >= 2 before writing.
  3. Validate size at generation time with Number.isInteger(size) && size >= 2.

Example fix

// before
LUT_3D_SIZE 2.5

// after
LUT_3D_SIZE 32
Defensive patterns

Strategy: try-catch

Validate before calling

function parseLutSizeSafe(value: string | undefined): number {
  const n = value == null ? NaN : Number(value);
  if (!Number.isInteger(n) || n < 2) throw new Error(`Size must be integer >= 2, got ${value}`);
  return n;
}

Try / catch

try {
  parseCubeLut(fileText);
} catch (err) {
  if (err instanceof CubeLutParseError && /must be an integer greater than 1/.test(err.message)) {
    // report and ask for a valid size
  } else throw err;
}

Prevention

When it happens

Trigger: 'LUT_3D_SIZE 1', 'LUT_3D_SIZE 2.5', 'LUT_3D_SIZE 0', or 'LUT_3D_SIZE -4'.

Common situations: Author typed 1 expecting 'minimal'; a float slipped in from a templating system; a default/uninitialized value of 0 or 1 written by buggy export code.

Related errors


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