heygen-com/hyperframes · error · Error

LUT for " " is not a valid .cube

Error message

LUT for "${cell.label}" is not a valid .cube: ${normalizeErrorMessage(err)}

What it means

Thrown by prepareGradeCompareTempProject when a LUT file exists and was read, but failed validation by `parseCubeLut(lutText, { maxSize: 64 })`. The .cube parser enforces the standard format and a 64-entry size cap; a corrupt, truncated, oversized, or non-.cube file is rejected before staging so the render doesn't fail later in the browser with an opaque shader error.

Solutions

  1. Open the named .cube file and verify it is a valid 3D .cube LUT with a LUT_3D_SIZE line ≤ 64.
  2. Re-export or re-download the LUT from its source in binary mode.
  3. If the LUT is genuinely larger than 64 points, downsample it with a LUT tool — HyperFrames will not raise the cap.
  4. Check the inner error message (appended after the colon) for the specific parse failure.
Defensive patterns

Strategy: validation

Validate before calling

// Validate a .cube file out-of-band before grading
import { parseCubeLut } from "@hyperframes/core";
import { readFileSync } from "node:fs";
function assertValidCube(path: string): void {
  const text = readFileSync(path, "utf-8");
  parseCubeLut(text, { maxSize: 64 }); // throws on invalid
}

Try / catch

try {
  await prepareGradeCompareTempProject(opts);
} catch (err) {
  if (/not a valid .cube/.test((err as Error).message))) {
    // re-derive or replace the offending LUT; message names the cell + inner cause
  }
  throw err;
}

Prevention

When it happens

Trigger: A .cube file that is malformed (bad header, wrong line counts, non-numeric rows), exceeds 64 grid points, is actually a different format with a .cube extension, or was truncated by a bad download/git checkout.

Common situations: Downloading a 1D LUT and renaming to .cube; a text-mode FTP/git operation that mangled line endings or truncated the file; a LUT exported at 65+ points (the cap is 64); copy-paste introducing stray characters.

Related errors


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

Appendix: source

Thrown at packages/cli/src/commands/grade-compare.ts:449

  const tempDir = mkdtempSync(join(tmpdir(), "hf-grade-compare-"));
  try {
    const frameFileName = opts.frameFileName ?? frameFileNameForPath(opts.framePath);
    writeFileSync(join(tempDir, frameFileName), opts.frameBuffer);

    let lutIndex = 0;
    const stagedCells = opts.cells.map((cell) => {
      const lutSrc = lutSrcFromGrading(cell.grading);
      if (!lutSrc) return cell;

      const sourcePath = resolveFromBase(opts.projectDir, lutSrc);
      if (!existsSync(sourcePath)) {
        throw new Error(`LUT file not found for "${cell.label}": ${sourcePath}`);
      }
      const lutText = readFileSync(sourcePath, "utf-8");
      try {
        parseCubeLut(lutText, { maxSize: 64 });
      } catch (err) {
        throw new Error(
          `LUT for "${cell.label}" is not a valid .cube: ${normalizeErrorMessage(err)}`,
        );
      }
      const lutExt = extname(sourcePath) || ".cube";
      const stagedName = `lut-${lutIndex}${lutExt}`;
      lutIndex += 1;
      copyFileSync(sourcePath, join(tempDir, stagedName));
      return {
        label: cell.label,
        grading: rewriteGradingLutSrc(cell.grading, stagedName),
      };
    });

    const html = buildGradeCompareHtml({
      cells: stagedCells,
      frameSrc: frameFileName,
      frameWidth: opts.frameWidth,
      frameHeight: opts.frameHeight,

View on GitHub (pinned to c2996c8626)