heygen-com/hyperframes · error · Error
Invalid selector: ${selector}
Error message
Invalid selector: ${selector} What it means
Thrown by selectMediaElement() in packages/cli/src/commands/media-treatment.ts:415. It wraps queryIncludingTemplates -> querySelectorAll in try/catch; if the underlying DOM (parseHTML/linkedom) throws a DOMException for a malformed selector, the catch rethrows this friendlier message. Note it fires only when the selector is syntactically invalid — a valid selector that matches nothing is a different error.
Source
Thrown at packages/cli/src/commands/media-treatment.ts:425
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" } {
const document = parseSourceDocument(source);
let matches: Element[];
try {
matches = queryIncludingTemplates(document, selector);
} catch {
throw new Error(`Invalid selector: ${selector}`);
}
if (matches.length === 0) throw new Error(`Selector did not match: ${selector}`);
if (selectorIndex === undefined && matches.length > 1) {
throw new Error(
`Selector matched ${matches.length} elements; use a unique selector or --selector-index`,
);
}
const resolvedIndex = selectorIndex ?? 0;
const element = matches[resolvedIndex];
if (!element) {
throw new Error(`--selector-index ${resolvedIndex} is outside ${matches.length} matches`);
}
const tag = element.tagName.toLowerCase();
if (tag !== "img" && tag !== "video") {
throw new Error(`Color grading requires an <img> or <video>; selector matched <${tag}>`);
}
return { element, selectorIndex: resolvedIndex, tag };View on GitHub (pinned to c2996c8626)
Solutions
- Test the selector in a browser devtools console against the same HTML; if it throws there, it throws here.
- Escape special characters (e.g. '#hero.main' should be '#hero\\.main' or use [id='hero.main']).
- Simplify the selector to confirm syntax, then add complexity back.
- Use --dry-run --json to iterate quickly without writing.
Example fix
# before -- invalid: stray colon / unbalanced
hyperframes media-treatment --selector 'img[' --apply --grading '{...}'
# after
hyperframes media-treatment --selector 'img.hero' --apply --grading '{...}' Defensive patterns
Strategy: validation
Validate before calling
import { parseHTML } from 'linkedom';
function isValidSelector(selector: string, source: string): boolean {
const { document } = parseHTML(source);
try {
document.querySelectorAll(selector);
return true;
} catch {
return false;
}
} Type guard
function isValidSelectorSyntax(selector: string): boolean {
try {
document.querySelector(selector);
return true;
} catch {
return false;
}
} Try / catch
try {
selectMediaElement(source, selector);
} catch (error) {
if (/Invalid selector/.test(String(error))) {
// ask the caller for a syntactically valid CSS selector
throw new Error(`Selector syntax invalid: ${selector}`);
}
throw error;
} Prevention
- Test selectors in browser devtools or with linkedom's querySelectorAll before passing them to the CLI.
- Escape special characters in ids/classes (use attribute selectors for ids containing dots).
- Avoid pseudo-classes linkedom doesn't implement.
When it happens
Trigger: Passing `--selector` with invalid CSS syntax: unbalanced brackets, unsupported pseudo-class, illegal combinators, stray characters, or unescaped special characters.
Common situations: Typo in the selector; copy-paste with hidden characters; selectors using pseudo-classes linkedom doesn't support; ids/classes starting with a digit and not escaped.
Related errors
- Selector did not match: ${selector}
- Selector matched ${matches.length} elements; use a unique se
- --selector-index ${resolvedIndex} is outside ${matches.lengt
- Color grading requires an <img> or <video>; selector matched
- Cannot merge a grading patch into an unresolved whole-grade
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/7b5c598be02171ec.
Report an issue: GitHub.