heygen-com/hyperframes · error · Error

--selector-index must be a non-negative integer

Error message

--selector-index must be a non-negative integer

What it means

Thrown by parseSelectorIndex() in packages/cli/src/commands/media-treatment.ts:470. It Number()-coerces the raw --selector-index arg and requires Number.isInteger AND value >= 0. Negative, fractional, or non-numeric values all throw.

Source

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

  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);
  if (!src) throw new Error("Selected media has no analyzable src");
  return src;
}

export function resolveMediaTreatmentSource(
  projectDir: string,
  compositionFile: string,
  source: string,

View on GitHub (pinned to c2996c8626)

Solutions

  1. Use a 0-based non-negative integer (0, 1, 2, ...).
  2. For 'last element', first count matches, then pass count-1.
  3. If you want uniqueness, prefer a more specific selector over an index.

Example fix

# before
hyperframes media-treatment --selector 'img' --selector-index -1 ...
hyperframes media-treatment --selector 'img' --selector-index 1.5 ...
# after
hyperframes media-treatment --selector 'img' --selector-index 0 ...
Defensive patterns

Strategy: validation

Validate before calling

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;
}

Type guard

function isValidSelectorIndex(raw: string | undefined): raw is `${number}` {
  if (raw === undefined) return false;
  const n = Number(raw);
  return Number.isInteger(n) && n >= 0;
}

Try / catch

try {
  parseSelectorIndex(raw);
} catch (error) {
  if (/must be a non-negative integer/.test(String(error))) {
    // default to 0 or ask the user for a valid index
    parseSelectorIndex('0');
  } else throw error;
}

Prevention

When it happens

Trigger: Passing --selector-index with a negative number (e.g. -1 expecting 'last'), a decimal (e.g. 1.5), or a non-numeric string.

Common situations: Assuming -1 means 'last index'; passing a float by mistake; copy-paste artifacts; shell quoting that leaves an empty or malformed value.

Related errors


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