heygen-com/hyperframes · error · Error
--source must be 'sparticuz' or 'chrome-headless-shell' (got
Error message
--source must be 'sparticuz' or 'chrome-headless-shell' (got ${v}) What it means
The --source flag selects which Chromium provider gets bundled into the Lambda ZIP. It accepts exactly two values: 'sparticuz' (the lightweight @sparticuz/chromium Lambda-optimized build) and 'chrome-headless-shell' (the heavier Puppeteer fallback). The parseArgs function rejects any other value at argument-parsing time, before any build work begins.
Source
Thrown at packages/aws-lambda/scripts/build-zip.ts:90
// MiB) + bundled Node deps put us close to the ceiling. Chrome itself
// decompresses into Lambda's `/tmp` at cold start, which has its own
// 10 GiB budget, so the unzipped /var/task footprint above is what
// actually competes with Lambda's 250 MiB limit.
maxUnzippedBytes: 248 * 1024 * 1024,
// Lambda's only zipped-size cap is for direct console/CLI uploads (50
// MiB); S3-deployed functions are bounded by the unzipped ceiling. We
// gate at 150 MiB to flag a sudden bundle-size regression without
// false-failing on the natural ~100 MiB sparticuz + ffmpeg payload.
maxZippedBytes: 150 * 1024 * 1024,
};
function parseArgs(argv: string[]): BuildOptions {
const opts = { ...DEFAULT_OPTIONS };
for (const arg of argv.slice(2)) {
if (arg.startsWith("--source=")) {
const v = arg.slice("--source=".length);
if (v !== "sparticuz" && v !== "chrome-headless-shell") {
throw new Error(`--source must be 'sparticuz' or 'chrome-headless-shell' (got ${v})`);
}
opts.source = v;
} else if (arg.startsWith("--max-unzipped=")) {
opts.maxUnzippedBytes = Number.parseInt(arg.slice("--max-unzipped=".length), 10);
} else if (arg.startsWith("--max-zipped=")) {
opts.maxZippedBytes = Number.parseInt(arg.slice("--max-zipped=".length), 10);
} else if (arg === "--help") {
console.log(
"Usage: tsx build-zip.ts [--source=sparticuz|chrome-headless-shell]\n" +
" [--max-unzipped=<bytes>] [--max-zipped=<bytes>]",
);
process.exit(0);
} else {
throw new Error(`Unknown flag: ${arg}`);
}
}
return opts;
}View on GitHub (pinned to c2996c8626)
Solutions
- Use exactly --source=sparticuz or --source=chrome-headless-shell.
- Run 'tsx build-zip.ts --help' to see the accepted values.
- Omit the flag entirely to use the default source (sparticuz).
Example fix
// before tsx build-zip.ts --source=chrome // after tsx build-zip.ts --source=chrome-headless-shell
Defensive patterns
Strategy: validation
Validate before calling
const VALID_SOURCES = ["sparticuz", "chrome-headless-shell"] as const;
const source = process.argv.find((a) => a.startsWith("--source="))?.slice("--source=".length);
if (source !== undefined && !VALID_SOURCES.includes(source as any)) {
console.error(`Invalid --source. Valid: ${VALID_SOURCES.join(", ")}`);
process.exit(1);
} Type guard
function isValidSource(v: string): v is "sparticuz" | "chrome-headless-shell" {
return v === "sparticuz" || v === "chrome-headless-shell";
} Prevention
- Validate --source in CI before invoking build-zip.ts.
- Use a shared shell helper that constrains --source to the two accepted values.
- Document the accepted values in the CI pipeline definition.
When it happens
Trigger: Running build-zip.ts with --source set to anything other than 'sparticuz' or 'chrome-headless-shell' — e.g., --source=chrome, --source=chromium, --source=puppeteer, or a typo like --source=spartucus.
Common situations: Copy-pasting an outdated CI command; typos in GitHub Actions YAML; muscle memory from a different tool's flag names; trying a shorthand that was never supported.
Related errors
- Unknown flag: ${arg}
- [build-zip] unzipped bundle ${formatBytes(unzippedBytes)} ex
- [build-zip] zip ${formatBytes(zippedBytes)} exceeds ZIP size
- [build-zip] ${label} at ${path} is not a Linux x86-64 ELF ex
- --executable-path requires a path
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/7e3cade15ced304a.
Report an issue: GitHub.