{"record":{"id":"5cc23755e0af3fa6","repo":"heygen-com/hyperframes","slug":"could-not-persist-selector-options-selector","errorCode":null,"errorMessage":"Could not persist selector: ${options.selector}","messagePattern":"Could not persist selector: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/cli/src/commands/media-treatment.ts","lineNumber":466,"sourceCode":"  options: ApplyMediaTreatmentOptions,\n): ApplyMediaTreatmentResult {\n  const { element, selectorIndex, tag } = selectMediaElement(\n    source,\n    options.selector,\n    options.selectorIndex,\n  );\n  const before = parseStoredGrading(element.getAttribute(HF_COLOR_GRADING_ATTR));\n\n  const value = options.clear ? null : serializeGradingPatch(before, options.grading);\n\n  const changed = element.getAttribute(HF_COLOR_GRADING_ATTR) !== value;\n  const after = parseStoredGrading(value);\n  if (!changed) return { html: source, changed: false, tag, value, before, after };\n\n  const patched = patchElementInHtml(source, { selector: options.selector, selectorIndex }, [\n    { type: \"attribute\", property: HF_COLOR_GRADING_ATTR, value },\n  ]);\n  if (!patched.matched) throw new Error(`Could not persist selector: ${options.selector}`);\n  return { html: patched.html, changed: true, tag, value, before, after };\n}\n\nfunction parseSelectorIndex(raw: string | undefined): number | undefined {\n  if (raw === undefined) return undefined;\n  const value = Number(raw);\n  if (!Number.isInteger(value) || value < 0) {\n    throw new Error(\"--selector-index must be a non-negative integer\");\n  }\n  return value;\n}\n\nfunction mediaSourceForElement(element: Element): string {\n  const src =\n    element.getAttribute(\"src\") ??\n    (element.tagName.toLowerCase() === \"video\"\n      ? element.querySelector(\"source\")?.getAttribute(\"src\")\n      : null);","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/cli/src/commands/media-treatment.ts#L448-L484","documentation":"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.","triggerScenarios":"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.","commonSituations":"HTML with unusual comment placement, conditional comments, <template> fragments, or partial markup that the two engines normalize differently; very large/deeply nested files.","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."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"import { patchElementInHtml } from '@hyperframes/studio-server/source-mutation';\n\nfunction canPersist(source: string, selector: string, index: number): boolean {\n  const result = patchElementInHtml(source, { selector, selectorIndex: index }, []);\n  return result.matched;\n}","typeGuard":null,"tryCatchPattern":"try {\n  applyMediaTreatmentToHtml(source, opts);\n} catch (error) {\n  if (/Could not persist selector/.test(String(error))) {\n    // simplify surrounding HTML, use a more specific selector, then retry\n    throw new Error('Read/write parser divergence — simplify the HTML around the target and retry');\n  }\n  throw error;\n}","preventionTips":["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."],"tags":["html","media-treatment","internal","source-mutation"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}