heygen-com/hyperframes · error · CubeLutParseError

${keyword} expects three numbers

Error message

${keyword} expects three numbers

What it means

parseVec3 expects exactly three whitespace-separated numbers after DOMAIN_MIN or DOMAIN_MAX (one per RGB channel). The throw at line 55 fires when the token count is not three, before any token is parsed as a number.

Source

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

  for (let i = 0; i < line.length; i++) {
    const char = line[i];
    if (char === '"') inQuote = !inQuote;
    if (char === "#" && !inQuote) return line.slice(0, i);
  }
  return line;
}

function parseFiniteNumber(value: string, lineNumber: number): number {
  const parsed = Number(value);
  if (!Number.isFinite(parsed)) {
    throw new CubeLutParseError(`Invalid number "${value}"`, lineNumber);
  }
  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 {

View on GitHub (pinned to c2996c8626)

Solutions

  1. Ensure each DOMAIN_MIN / DOMAIN_MAX line has exactly three numeric tokens.
  2. If you want a uniform domain, repeat the same value three times (e.g. 'DOMAIN_MIN 0 0 0').
  3. Re-export the LUT from the originating color tool.

Example fix

// before
DOMAIN_MIN 0 0
DOMAIN_MAX 1 1 1

// after
DOMAIN_MIN 0 0 0
DOMAIN_MAX 1 1 1
Defensive patterns

Strategy: try-catch

Validate before calling

function assertVec3Header(line: string): void {
  const parts = line.trim().split(/\s+/);
  const keyword = (parts[0] ?? '').toUpperCase();
  if ((keyword === 'DOMAIN_MIN' || keyword === 'DOMAIN_MAX') && parts.length !== 4) {
    throw new Error(`${keyword} needs 3 numbers, got ${parts.length - 1}`);
  }
}

Try / catch

try {
  parseCubeLut(fileText);
} catch (err) {
  if (err instanceof CubeLutParseError && /expects three numbers/.test(err.message)) {
    // point user at the header line in err.lineNumber
  } else throw err;
}

Prevention

When it happens

Trigger: A .cube line like 'DOMAIN_MIN 0 0' (two values), 'DOMAIN_MIN 0 0 0 0' (four), or 'DOMAIN_MIN' (none).

Common situations: Hand-edited header with a missing channel; copy-paste from a 1D LUT spec; a stray extra column from a spreadsheet export.

Related errors


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