heygen-com/hyperframes · error · Error
Could not persist selector: ${options.selector}
Error message
Could not persist selector: ${options.selector} What it means
Thrown by applyMediaTreatmentToHtml() in packages/cli/src/commands/media-treatment.ts:466. selectMediaElement successfully found the element via parseHTML (linkedom), but the separate patchElementInHtml writer (from @hyperframes/studio-server/source-mutation) returned matched:false — it could not relocate the element to write the data-hf-color-grading attribute. The read path and write path use different HTML engines, so edge-case HTML can diverge.
Source
Thrown at packages/cli/src/commands/media-treatment.ts:466
options: ApplyMediaTreatmentOptions,
): ApplyMediaTreatmentResult {
const { element, selectorIndex, tag } = selectMediaElement(
source,
options.selector,
options.selectorIndex,
);
const before = parseStoredGrading(element.getAttribute(HF_COLOR_GRADING_ATTR));
const value = options.clear ? null : serializeGradingPatch(before, options.grading);
const changed = element.getAttribute(HF_COLOR_GRADING_ATTR) !== value;
const after = parseStoredGrading(value);
if (!changed) return { html: source, changed: false, tag, value, before, after };
const patched = patchElementInHtml(source, { selector: options.selector, selectorIndex }, [
{ type: "attribute", property: HF_COLOR_GRADING_ATTR, value },
]);
if (!patched.matched) throw new Error(`Could not persist selector: ${options.selector}`);
return { html: patched.html, changed: true, tag, value, before, after };
}
function parseSelectorIndex(raw: string | undefined): number | undefined {
if (raw === undefined) return undefined;
const value = Number(raw);
if (!Number.isInteger(value) || value < 0) {
throw new Error("--selector-index must be a non-negative integer");
}
return value;
}
function mediaSourceForElement(element: Element): string {
const src =
element.getAttribute("src") ??
(element.tagName.toLowerCase() === "video"
? element.querySelector("source")?.getAttribute("src")
: null);View on GitHub (pinned to c2996c8626)
Solutions
- Simplify the HTML immediately around the target element (remove comments/conditional blocks/temporary wrapper templates) and retry.
- Use a more specific selector so the patcher has less ambiguity.
- Run `hyperframes lint` on the composition — structural HTML issues are often flagged there too.
- If the HTML is valid and the error persists, it's a parser-divergence bug; report it with the minimal HTML repro.
Defensive patterns
Strategy: try-catch
Validate before calling
import { patchElementInHtml } from '@hyperframes/studio-server/source-mutation';
function canPersist(source: string, selector: string, index: number): boolean {
const result = patchElementInHtml(source, { selector, selectorIndex: index }, []);
return result.matched;
} Try / catch
try {
applyMediaTreatmentToHtml(source, opts);
} catch (error) {
if (/Could not persist selector/.test(String(error))) {
// simplify surrounding HTML, use a more specific selector, then retry
throw new Error('Read/write parser divergence — simplify the HTML around the target and retry');
}
throw error;
} Prevention
- Keep composition HTML well-formed around media targets (avoid unusual comment/CDATA/template wrapping).
- Run `hyperframes lint` to catch structural HTML issues that can cause parser divergence.
- Use specific selectors to reduce ambiguity for the source-mutation writer.
- Report persistent cases as a bug with a minimal HTML repro.
When it happens
Trigger: The composition HTML around the target element is structured in a way patchElementInHtml can't match: malformed HTML, unusual template/comment/CDATA wrapping, self-closing edge cases, or elements linkedom parses differently from the patcher.
Common situations: HTML with unusual comment placement, conditional comments, <template> fragments, or partial markup that the two engines normalize differently; very large/deeply nested files.
Related errors
- Failed to bundle beat analyzer
- beat analyzer not loaded
- Missing browser script ${name}
- Cannot merge a grading patch into an unresolved whole-grade
- --grading must be valid HyperFrames color-grading JSON
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/5cc23755e0af3fa6.
Report an issue: GitHub.