heygen-com/hyperframes · error · Error
Selector matched ${matches.length} elements; use a unique se
Error message
Selector matched ${matches.length} elements; use a unique selector or --selector-index What it means
Thrown by selectMediaElement() in packages/cli/src/commands/media-treatment.ts:428. When a selector matches more than one element and --selector-index is not supplied, it refuses to pick the first silently (the code comment elsewhere calls out 'first-match-only sampling silently passes for siblings'). You must disambiguate.
Source
Thrown at packages/cli/src/commands/media-treatment.ts:429
}
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 };
}
export function applyMediaTreatmentToHtml(
source: string,View on GitHub (pinned to c2996c8626)
Solutions
- Use a more specific selector: add an id, a parent scope (e.g. '#scene1 img'), or a unique class.
- Or pass --selector-index <n> to pick the nth match (0-based).
- Run `hyperframes media-treatment --selector '<sel>' --dry-run --json` to see how many matches before writing.
Example fix
# before -- ambiguous
hyperframes media-treatment --selector 'img' --grading '{...}' --apply
# after -- unique selector
hyperframes media-treatment --selector '#hero' --grading '{...}' --apply
# or by index
hyperframes media-treatment --selector 'img' --selector-index 2 --grading '{...}' --apply Defensive patterns
Strategy: validation
Validate before calling
import { parseHTML } from 'linkedom';
function selectorIsUnique(selector: string, source: string): boolean {
const { document } = parseHTML(source);
return document.querySelectorAll(selector).length === 1;
} Try / catch
try {
selectMediaElement(source, selector);
} catch (error) {
if (/Selector matched .* elements/.test(String(error))) {
// either narrow the selector or pass --selector-index
selectMediaElement(source, narrowerSelector);
} else throw error;
} Prevention
- Prefer id-based or scoped selectors for uniqueness.
- Pass --selector-index when you intentionally target one of several matches.
- Use --dry-run --json to see match counts before writing.
When it happens
Trigger: A selector like 'img', 'video', or '.media' that matches multiple elements in the composition, with no --selector-index provided.
Common situations: Common tag/class selectors; multiple media elements in one scene; refactoring introduced a second matching element; intended a specific one but used a generic selector.
Related errors
- Invalid selector: ${selector}
- Selector did not match: ${selector}
- --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/164945095747cde8.
Report an issue: GitHub.