heygen-com/hyperframes · error · Error

--selector-index ${resolvedIndex} is outside ${matches.lengt

Error message

--selector-index ${resolvedIndex} is outside ${matches.length} matches

What it means

Thrown by selectMediaElement() in packages/cli/src/commands/media-treatment.ts:436. After resolving selectorIndex (default 0), it indexes into the matches array; if that slot is undefined (index >= matches.length), it throws. The reported numbers let you see the actual match count.

Source

Thrown at packages/cli/src/commands/media-treatment.ts:437

): { 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,
  options: ApplyMediaTreatmentOptions,
): ApplyMediaTreatmentResult {
  const { element, selectorIndex, tag } = selectMediaElement(
    source,
    options.selector,
    options.selectorIndex,
  );
  const before = parseStoredGrading(element.getAttribute(HF_COLOR_GRADING_ATTR));

View on GitHub (pinned to c2996c8626)

Solutions

  1. Use a 0-based index strictly less than the reported match count.
  2. For 'last', first count matches with --dry-run, then pass count-1.
  3. Use a more specific selector so the index isn't needed.

Example fix

# before -- only 2 matches, asked for index 5
hyperframes media-treatment --selector 'img' --selector-index 5 ...
# after
hyperframes media-treatment --selector 'img' --selector-index 1 ...
Defensive patterns

Strategy: validation

Validate before calling

import { parseHTML } from 'linkedom';

function indexInBounds(selector: string, source: string, index: number): boolean {
  const { document } = parseHTML(source);
  return index >= 0 && index < document.querySelectorAll(selector).length;
}

Try / catch

try {
  selectMediaElement(source, selector, index);
} catch (error) {
  if (/--selector-index .* is outside/.test(String(error))) {
    // re-query to find the valid range and pick a valid index
    throw new Error('selector-index out of range; check match count');
  }
  throw error;
}

Prevention

When it happens

Trigger: Passing `--selector-index N` where N is greater than or equal to the number of elements the selector matched.

Common situations: Off-by-one (assuming 1-based or 'last'); assuming there are more matches than there are; copy-pasting an index from a different composition.

Related errors


AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12). Data as JSON: /api/errors/7125df4b0ba09966. Report an issue: GitHub.