heygen-com/hyperframes · error · Error

need 2+ paths to compare

Error message

need 2+ paths to compare

What it means

Thrown by parseCompareArgs() when fewer than 2 positional composition paths survive parsePathArgs. A comparison sheet is meaningless with one cell, so the command refuses rather than rendering a single-frame image. parsePathArgs keeps only string positionals, trims them, and drops empties, so the count can shrink below what was typed.

Solutions

  1. Pass two or more composition paths (directories with index.html or .html files)
  2. If using a glob, verify it expands: run `echo ./variants/*` first
  3. Quote each path separately rather than as one combined argument

Example fix

// before
hyperframes compare ./variants/a
// after
hyperframes compare ./variants/a ./variants/b
Defensive patterns

Strategy: validation

Validate before calling

const paths = (args._ ?? []).filter((v): v is string => typeof v === 'string').map(v => v.trim()).filter(Boolean);
if (paths.length < 2) {
  throw new Error(`need 2+ paths to compare (got ${paths.length})`);
}

Prevention

When it happens

Trigger: Running `hyperframes compare` with zero positionals; with one positional (`compare ./a`); or with positionals that are non-string/empty-after-trim (e.g. a shell glob that expanded to nothing, or quoted empty strings).

Common situations: Forgetting the second variant path; a glob like `./variants/*` that matched nothing because the directory is empty or the cwd is wrong; quoting mistakes that collapse args.

Related errors


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

Appendix: source

Thrown at packages/cli/src/commands/compare.ts:132

function defaultCompareCols(cellCount: number): number {
  return Math.max(1, Math.min(MAX_COLUMNS, Math.ceil(Math.sqrt(cellCount))));
}

export function parseCompareArgs(
  args: {
    _?: readonly unknown[];
    labels?: unknown;
    out?: unknown;
    at?: unknown;
    cols?: unknown;
    json?: unknown;
    timeout?: unknown;
  },
  cwd = process.cwd(),
): ParsedCompareArgs {
  const paths = parsePathArgs(args);
  if (paths.length < 2) {
    throw new Error("need 2+ paths to compare");
  }

  const labels = parseLabels(args.labels, paths.length);
  const variants = paths.map((input, index) => ({
    label: labels?.[index] ?? defaultLabelForPath(input),
    inputPath: resolveFromBase(cwd, input),
    displayPath: displayPathFromInput(cwd, input),
  }));

  return {
    variants,
    outPath: resolveFromBase(cwd, readOptionalString(args.out) ?? "compare.png"),
    atSeconds: parseAtSeconds(args.at),
    cols: parseColumns(args.cols),
    json: args.json === true,
    timeoutMs:
      Number.parseInt(readOptionalString(args.timeout) ?? "", 10) ||
      DEFAULT_RENDER_READY_TIMEOUT_MS,

View on GitHub (pinned to c2996c8626)