heygen-com/hyperframes · error · Error
[build-zip] npm install into staging failed (status ${result
Error message
[build-zip] npm install into staging failed (status ${result.status}) What it means
The staging step runs 'npm install --no-package-lock --no-audit --no-fund --omit=dev --omit=optional' inside the staging directory to populate node_modules with production deps. If npm exits non-zero, the build aborts because a partial install would ship a broken or incomplete zip.
Source
Thrown at packages/aws-lambda/scripts/build-zip.ts:283
};
if (source === "sparticuz") {
(pkg.dependencies as Record<string, string>)["@sparticuz/chromium"] =
readDepVersion("@sparticuz/chromium");
}
writeFileSync(join(stagingDir, "package.json"), JSON.stringify(pkg, null, 2));
// --no-package-lock so we don't pollute staging with a lockfile we don't
// ship; --no-audit/--no-fund just for log noise.
const result = spawnSync(
"npm",
["install", "--no-package-lock", "--no-audit", "--no-fund", "--omit=dev", "--omit=optional"],
{
cwd: stagingDir,
stdio: "inherit",
},
);
if (result.status !== 0) {
throw new Error(`[build-zip] npm install into staging failed (status ${result.status})`);
}
console.log(`[build-zip] staged node_modules via npm install`);
}
function readDepVersion(moduleName: string): string {
// Resolve the EXACT version bun installed into the workspace, not the
// semver range declared in package.json. The staging-dir npm install
// runs with `--no-package-lock`, so a caret range would float to the
// latest registry version at build time — diverging from what the
// workspace tests ran against and breaking ZIP-content determinism
// across consecutive builds. The lockfile pin gives us reproducibility.
const lockText = readFileSync(join(monorepoRoot, "bun.lock"), "utf-8");
// bun.lock lines look like:
// "puppeteer-core": ["puppeteer-core@24.43.1", "", { ... }, "sha512-..."],
const re = new RegExp(
`"${moduleName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}":\\s*\\["${moduleName.replace(
/[.*+?^${}()|[\]\\]/g,
"\\$&",View on GitHub (pinned to c2996c8626)
Solutions
- Run the same npm install command manually in the staging directory to see the error output.
- Check network and registry connectivity from the build environment.
- Clear the npm cache: npm cache clean --force.
- Verify npm is installed and on PATH in the build container.
- Check that the staged package.json has valid, resolvable dependency versions.
Defensive patterns
Strategy: retry
Validate before calling
import { spawnSync } from "node:child_process";
const check = spawnSync("npm", ["--version"], { encoding: "utf-8" });
if (check.status !== 0) {
console.error("npm is not available on PATH. Install Node.js/npm first.");
process.exit(1);
} Try / catch
try {
// ... staging npm install logic ...
} catch (e) {
if (e instanceof Error && e.message.includes("npm install into staging failed")) {
console.error("npm install failed. Check network and registry. Retrying...");
// retry once with a clean npm cache
}
throw e;
} Prevention
- Ensure the build environment has network access to the npm registry.
- Pin dependency versions in package.json to avoid unresolvable ranges.
- Pre-warm the npm cache in CI Docker images.
When it happens
Trigger: npm install exits non-zero — caused by network or registry errors, an unresolvable dependency version, a broken package.json in staging, npm not found on PATH, or a postinstall script failure.
Common situations: CI without network access; a transitive dependency was unpublished or yanked; npm cache corruption; npm not installed in the build Docker image.
Related errors
- [build-zip] could not resolve ${moduleName} from ${packageRo
- [build-zip] ffmpeg-static binary missing at ${ffmpegBinary}.
- whisper-cpp build failed. Ensure cmake and a C compiler are
- --source must be 'sparticuz' or 'chrome-headless-shell' (got
- Unknown flag: ${arg}
AI-assisted analysis of heygen-com/hyperframes@c2996c8626 (2026-08-12).
Data as JSON: /api/errors/b00dc335c6dfbb0a.
Report an issue: GitHub.