heygen-com/hyperframes · error · Error
[build-zip] zip ${formatBytes(zippedBytes)} exceeds ZIP size
Error message
[build-zip] zip ${formatBytes(zippedBytes)} exceeds ZIP size limit ${formatBytes(opts.maxZippedBytes)}. What it means
After zipping, the build checks the compressed handler.zip size against opts.maxZippedBytes (default 150 MiB). This is an early-warning guard for bundle-size regressions, set to flag a sudden increase without false-failing on the natural ~100 MiB sparticuz + ffmpeg payload.
Source
Thrown at packages/aws-lambda/scripts/build-zip.ts:162
// 5. Compute the unzipped size BEFORE zipping so we fail loud when over budget.
const unzippedBytes = directorySizeBytes(stagingDir);
console.log(`[build-zip] unzipped staging size: ${formatBytes(unzippedBytes)}`);
if (unzippedBytes > opts.maxUnzippedBytes) {
throw new Error(
`[build-zip] unzipped bundle ${formatBytes(unzippedBytes)} exceeds limit ${formatBytes(
opts.maxUnzippedBytes,
)} (Lambda ZIP ceiling: 250 MiB unzipped). ` +
`Switch --source to the lighter option, or move Chrome to a Lambda Layer.`,
);
}
// 6. Build the ZIP.
const zipPath = join(distDir, "handler.zip");
zipDirectory(stagingDir, zipPath);
const zippedBytes = statSync(zipPath).size;
console.log(`[build-zip] zip size: ${formatBytes(zippedBytes)} → ${zipPath}`);
if (zippedBytes > opts.maxZippedBytes) {
throw new Error(
`[build-zip] zip ${formatBytes(zippedBytes)} exceeds ZIP size limit ${formatBytes(
opts.maxZippedBytes,
)}.`,
);
}
// 7. Sidecar manifest.
const manifest = {
builtAt: new Date().toISOString(),
durationMs: Date.now() - start,
source: opts.source,
unzippedBytes,
zippedBytes,
maxUnzippedBytes: opts.maxUnzippedBytes,
maxZippedBytes: opts.maxZippedBytes,
};
writeFileSync(join(distDir, "handler.zip.manifest.json"), JSON.stringify(manifest, null, 2));
View on GitHub (pinned to c2996c8626)
Solutions
- Switch to --source=sparticuz to reduce the zip size.
- Move large binaries (Chrome, ffmpeg) to a Lambda Layer.
- Raise --max-zipped=<bytes> if your deploy path (S3) supports a larger zip and the increase is intentional and reviewed.
Example fix
// before tsx build-zip.ts --source=chrome-headless-shell // after tsx build-zip.ts --source=sparticuz
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
const zipBytes = statSync(zipPath).size;
const MAX_ZIPPED = 150 * 1024 * 1024;
if (zipBytes > MAX_ZIPPED) {
console.error(`Zip ${zipBytes} exceeds limit ${MAX_ZIPPED}. Reduce bundle or use a Lambda Layer.`);
process.exit(1);
} Prevention
- Track zip size across builds as a regression metric.
- Use --source=sparticuz to keep the zip well under the threshold.
- Set --max-zipped deliberately, not as a workaround for bloat.
When it happens
Trigger: The final handler.zip is larger than maxZippedBytes. Happens with chrome-headless-shell source or when dependencies have grown significantly since the guard threshold was set.
Common situations: New dependencies inflating the bundle; using the heavier Chrome source; uncompressed or poorly compressing binaries in staging.
Related errors
- [build-zip] unzipped bundle ${formatBytes(unzippedBytes)} ex
- --source must be 'sparticuz' or 'chrome-headless-shell' (got
- [build-zip] ${label} at ${path} is not a Linux x86-64 ELF ex
- [validateConfig] config: Step Functions execution input is $
- Unknown flag: ${arg}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/641e38b463d20222.
Report an issue: GitHub.