heygen-com/hyperframes · error · Error
--cols must be a positive integer
Error message
--cols must be a positive integer
What it means
Thrown by parseColumns() in the `compare` command when --cols fails its integer check. The value is run through Number(raw), then rejected unless Number.isInteger(parsed) AND parsed >= 1. An empty/whitespace value never reaches here because readOptionalString returns undefined first. There is no upper bound enforced at this layer (defaultCompareCols later caps the auto-computed default at MAX_COLUMNS=4, but an explicit --cols accepts any positive integer).
Source
Thrown at packages/cli/src/commands/compare.ts:109
return labels;
}
function parseAtSeconds(value: unknown): number {
const raw = readOptionalString(value);
if (!raw) return 0;
const parsed = Number(raw);
if (!Number.isFinite(parsed) || parsed < 0) {
throw new Error("--at must be a non-negative number of seconds");
}
return parsed;
}
function parseColumns(value: unknown): number | undefined {
const raw = readOptionalString(value);
if (!raw) return undefined;
const parsed = Number(raw);
if (!Number.isInteger(parsed) || parsed < 1) {
throw new Error("--cols must be a positive integer");
}
return parsed;
}
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;
},View on GitHub (pinned to c2996c8626)
Solutions
- Pass a whole number >= 1, e.g. --cols 2 or --cols 4
- Omit --cols entirely to use the sqrt-based default (capped at 4)
- If the value comes from a variable, coerce with Math.max(1, Math.trunc(Number(v))) before passing
Example fix
// before hyperframes compare ./a ./b --cols 0 // after hyperframes compare ./a ./b --cols 2
Defensive patterns
Strategy: validation
Validate before calling
function parseColsSafe(raw: string | undefined): number | undefined {
if (!raw) return undefined;
const n = Number(raw);
if (!Number.isInteger(n) || n < 1) {
throw new Error(`--cols must be a positive integer (got ${JSON.stringify(raw)})`);
}
return n;
} Type guard
function isPositiveIntegerInput(raw: unknown): raw is string {
return typeof raw === 'string' &&
raw.trim().length > 0 &&
Number.isInteger(Number(raw)) &&
Number(raw) >= 1;
} Prevention
- Coerce dynamic values with Math.max(1, Math.trunc(Number(v))) before passing to --cols
- Omit --cols to accept the sqrt-based default rather than guessing
- Validate the value in your wrapper script before invoking the CLI
When it happens
Trigger: Passing `--cols 0` (fails the < 1 check), `--cols -1`, `--cols 2.5` (not an integer), `--cols abc` (Number yields NaN, not an integer), `--cols 1.5e1` (15, actually passes). Note `--cols 3.0` passes because Number('3.0')===3, and `--cols ' 3 '` passes because Number trims whitespace.
Common situations: Assuming 0 disables the grid; passing a float column count; a typo or shell variable expansion producing a non-numeric string; copying a value from a UI that emits decimals.
Related errors
- need 2+ paths to compare
- [handler] chunk URI at index ${i} is empty
- PLAN_V2_INTEGRITY_UNRECOVERABLE
- [s3Transport] expected s3:// URI, got: ${JSON.stringify(uri)
- [s3Transport] missing key in s3 URI: ${JSON.stringify(uri)}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/c4d716b56cf2cf8e.
Report an issue: GitHub.