heygen-com/hyperframes · error · CubeLutParseError

DOMAIN_MAX values must be greater than DOMAIN_MIN values

Error message

DOMAIN_MAX values must be greater than DOMAIN_MIN values

What it means

validateDomain rejects any axis where DOMAIN_MAX <= DOMAIN_MIN. The .cube format defines a per-channel input domain that the sampler maps into the LUT; a non-positive range on R, G, or B makes that mapping undefined. The check runs after the full file is parsed (line 179).

Source

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

  ];
}

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);
  return bare ? (bare[1] ?? "").trim() || null : null;
}

function isNumericDataLine(token: string): boolean {
  return /^[+-]?(?:\d|\.\d)/.test(token);
}

// fallow-ignore-next-line complexity
export function parseCubeLut(input: string, options: ParseCubeLutOptions = {}): CubeLut3D {
  const maxSize = options.maxSize ?? DEFAULT_MAX_CUBE_LUT_SIZE;
  let title: string | null = null;

View on GitHub (pinned to c2996c8626)

Solutions

  1. Ensure every channel of DOMAIN_MAX is strictly greater than the matching DOMAIN_MIN channel.
  2. If you do not need a custom domain, remove both DOMAIN_MIN and DOMAIN_MAX lines — the parser defaults to [0,0,0]..[1,1,1].
  3. Re-export from the source tool, which emits a consistent domain pair.

Example fix

// before
DOMAIN_MIN 0 0 0
DOMAIN_MAX 0.5 0.5 0.5
// (or swapped)
DOMAIN_MIN 1 1 1
DOMAIN_MAX 0 0 0

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

Strategy: try-catch

Validate before calling

function assertDomainValid(min: readonly number[], max: readonly number[]): void {
  if (max[0] <= min[0] || max[1] <= min[1] || max[2] <= min[2]) {
    throw new Error('DOMAIN_MAX must be > DOMAIN_MIN on every channel');
  }
}

Try / catch

try {
  parseCubeLut(fileText);
} catch (err) {
  if (err instanceof CubeLutParseError && /DOMAIN_MAX values must be greater/.test(err.message)) {
    // suggest removing custom domain lines to use the [0,0,0]..[1,1,1] default
  } else throw err;
}

Prevention

When it happens

Trigger: DOMAIN_MAX whose any component is <= the matching DOMAIN_MIN component — including equal values, swapped min/max, or a negative range. Note LUT_3D_INPUT_RANGE cannot trip this directly because it pre-checks max > min, but explicit DOMAIN_MIN/DOMAIN_MAX lines can.

Common situations: Swapping the DOMAIN_MIN and DOMAIN_MAX lines; setting both to [0,0,0]/[1,1,1] but then overriding only one; an inverted log domain from a mishandled linearization.

Related errors


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