heygen-com/hyperframes · error · Error
--grading must be valid HyperFrames color-grading JSON
Error message
--grading must be valid HyperFrames color-grading JSON
What it means
Thrown by serializeGradingPatch() in packages/cli/src/commands/media-treatment.ts:401. After the patch passes contract validation and is merged, normalizeHfColorGrading is called; if it returns null (the merged shape can't be normalized into a valid HyperFrames grading object), this fires. It is the semantic fallback for shapes that are structurally OK but semantically empty or incompatible.
Source
Thrown at packages/cli/src/commands/media-treatment.ts:401
isRecord(value) && isRecord(merged[key]) ? mergeGradingPatch(merged[key], value) : value;
}
return merged;
}
function serializeGradingPatch(before: unknown, patch: unknown): string | null {
assertKnownGradingShape(patch);
if (isColorGradingVariableRef(before) && isRecord(patch)) {
throw new Error("Cannot merge a grading patch into an unresolved whole-grade variable");
}
const current =
typeof before === "string" && !isColorGradingVariableRef(before) ? { preset: before } : before;
const grading = mergeGradingPatch(current, patch);
assertKnownGradingShape(grading);
if (containsColorGradingVariableRef(grading)) {
return typeof grading === "string" ? grading.trim() : JSON.stringify(grading);
}
const normalized = normalizeHfColorGrading(grading);
if (!normalized) throw new Error("--grading must be valid HyperFrames color-grading JSON");
return hasHfColorGradingAuthoredValues(normalized) ? serializeHfColorGrading(normalized) : null;
}
function queryIncludingTemplates(root: Document | Element, selector: string): Element[] {
const matches = Array.from(root.querySelectorAll(selector));
if (matches.length > 0) return matches;
for (const template of root.querySelectorAll("template")) {
const nested = queryIncludingTemplates(template, selector);
if (nested.length > 0) return nested;
}
return [];
}
function selectMediaElement(
source: string,
selector: string,
selectorIndex?: number,
): { element: Element; selectorIndex: number; tag: "img" | "video" } {View on GitHub (pinned to c2996c8626)
Solutions
- Confirm preset ids via `hyperframes media-treatment --capability presets --json` and palette ids via `--capability palettes --json`.
- Ensure the grading object has at least one authored value (the hasHfColorGradingAuthoredValues check downstream also requires this).
- Run with --dry-run --json to see whether the merged result is empty before writing.
- Compare against a known-good example from `--capability <family>` 'apply' blocks.
Example fix
# before -- preset typo passes shape check but fails normalize
hyperframes media-treatment -s '#hero' --grading '{"preset":"warm-daylite"}' --apply
# after
hyperframes media-treatment -s '#hero' --grading '{"preset":"warm-daylight"}' --apply Defensive patterns
Strategy: validation
Validate before calling
import { normalizeHfColorGrading } from '@hyperframes/core';
function normalizesToValid(value: unknown): boolean {
return normalizeHfColorGrading(value) !== null;
} Type guard
import { normalizeHfColorGrading, hasHfColorGradingAuthoredValues } from '@hyperframes/core';
function isNormalizableGrading(value: unknown): boolean {
const n = normalizeHfColorGrading(value);
return n !== null && hasHfColorGradingAuthoredValues(n);
} Try / catch
try {
serializeGradingPatch(before, patch);
} catch (error) {
if (/--grading must be valid HyperFrames color-grading JSON/.test(String(error))) {
// verify preset/palette ids exist; ensure >=1 authored value; retry
throw new Error('Grading normalized to nothing — check preset/palette ids and authored values');
}
throw error;
} Prevention
- Verify preset ids via --capability presets and palette ids via --capability palettes before use.
- Ensure the grading object has at least one authored value (not just a preset that resolves to identity).
- Always test with --dry-run --json first.
When it happens
Trigger: A --grading value that passes validateColorGradingContract but fails normalization: a preset id that doesn't exist, an object that normalizes to zero authored values, or a combination that yields nothing serializeHfColorGrading can emit.
Common situations: Preset name typo (valid shape, unknown preset); empty object after merge; referencing a palette id that doesn't resolve; values that the normalizer collapses to identity/no-op.
Related errors
- Cannot merge a grading patch into an unresolved whole-grade
- Invalid color grading for cell "${label}"
- Invalid color grading for cell "${cell.label}"
- Unknown media-treatment capability: ${id}
- Invalid color-grading ${issue.path}: ${issue.message}.${hint
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/bed864133c246fb7.
Report an issue: GitHub.