heygen-com/hyperframes · error · Error

Invalid color grading for cell "${cell.label}"

Error message

Invalid color grading for cell "${cell.label}"

What it means

Thrown by serializedGradingForCell() during buildGradeCompareHtml — the second normalization pass that serializes a cell's grading into the data-hf-color-grading attribute. It uses the exact same normalizeHfColorGrading as validateCell, so by the time a cell reaches here it should already be valid. Hitting it means a cell was constructed without validateCell, or its grading was mutated to an invalid shape between validation and serialization (e.g. by rewriteGradingLutSrc).

Source

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

  );
  return { cells: cells.slice(0, MAX_CANDIDATE_CELLS), truncated: true, total };
}

export function buildGradeCompareSuccessPayload(
  sheet: string,
  cells: number,
  capResult: CandidateCellCapResult,
): GradeCompareSuccessPayload {
  if (!capResult.truncated) {
    return { ok: true, sheet, cells };
  }
  return { ok: true, sheet, cells, truncated: true, total: capResult.total };
}

function serializedGradingForCell(cell: GradeCompareCell): string {
  const normalized = normalizeHfColorGrading(cell.grading);
  if (!normalized) {
    throw new Error(`Invalid color grading for cell "${cell.label}"`);
  }
  return serializeHfColorGrading(normalized);
}

function lutSrcFromGrading(grading: unknown): string | null {
  if (!isRecord(grading) || !hasOwn(grading, "lut")) return null;
  const lut = grading.lut;
  if (typeof lut === "string" && lut.trim()) return lut.trim();
  if (!isRecord(lut)) return null;
  const src = lut.src;
  return typeof src === "string" && src.trim() ? src.trim() : null;
}

function rewriteGradingLutSrc(grading: unknown, src: string): unknown {
  if (!isRecord(grading) || !hasOwn(grading, "lut")) return grading;
  const lut = grading.lut;
  const next = cloneRecord(grading);
  if (typeof lut === "string") {

View on GitHub (pinned to c2996c8626)

Solutions

  1. Always construct cells through validateCell, parseGradesFile, or resolveLutCells
  2. If mutating grading before serialization, re-run validateCell afterward
  3. Unit-test that each cell round-trips through normalizeHfColorGrading

Example fix

// before: hand-built cell bypasses validation
const cell = { label: "warm", grading: { enabled: false } };
// after: construct via validateCell so invalid shapes fail early
import { normalizeHfColorGrading } from "@hyperframes/core";
const ok = normalizeHfColorGrading(cell.grading);
if (!ok) throw new Error(`invalid grading for ${cell.label}`);
Defensive patterns

Strategy: type-guard

Validate before calling

import { normalizeHfColorGrading } from '@hyperframes/core';
// Always construct cells through validateCell so invalid shapes fail at the boundary,
// and re-validate after any mutation (e.g. LUT src rewrite).
const normalized = normalizeHfColorGrading(cell.grading);
if (!normalized) throw new Error(`invalid grading for ${cell.label}`);

Type guard

import { normalizeHfColorGrading } from '@hyperframes/core';
function isValidGrading(grading: unknown): boolean {
  return normalizeHfColorGrading(grading) !== null;
}

Prevention

When it happens

Trigger: A programmatic caller building GradeCompareCell objects directly and bypassing validateCell/parseGradesFile/resolveLutCells; a LUT-rewrite path that produced a malformed grading object; a cell whose grading is an object with enabled:false introduced after validation.

Common situations: Using the exported prepareGradeCompareTempProject with hand-built cells; a future grading-rewrite helper that does not preserve the valid shape.

Related errors


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