headroomlabs-ai/headroom · error · Error
tar failed for ${tarballPath}: ${result.stderr || result.std
Error message
tar failed for ${tarballPath}: ${result.stderr || result.stdout || "unknown error"} What it means
verify_npm_release_assets.mjs extracts `package/dist/package.json` from each release tarball by spawning `tar -xzf`. A nonzero exit status (or a null status when the `tar` binary cannot be spawned at all) throws with the captured stderr/stdout, or 'unknown error' when neither stream has content. This usually indicates a corrupt tarball or a missing/incompatible system tar.
Source
Thrown at scripts/verify_npm_release_assets.mjs:48
const tarballPaths = new Map();
function extractPackageJson(tarballPath) {
return extractJsonFromTarball(tarballPath, "package/package.json");
}
function extractDistPackageJson(tarballPath) {
return extractJsonFromTarball(tarballPath, "package/dist/package.json");
}
function extractJsonFromTarball(tarballPath, packageJsonPath) {
const workdir = mkdtempSync(path.join(tmpdir(), "headroom-npm-asset-"));
try {
const result = spawnSync("tar", ["-xzf", tarballPath, "-C", workdir], {
encoding: "utf8",
});
if (result.status !== 0) {
throw new Error(
`tar failed for ${tarballPath}: ${result.stderr || result.stdout || "unknown error"}`,
);
}
return JSON.parse(readFileSync(path.join(workdir, packageJsonPath), "utf8"));
} finally {
rmSync(workdir, { recursive: true, force: true });
}
}
function assertNoFileDependencies(pkg) {
for (const field of ["dependencies", "peerDependencies", "optionalDependencies"]) {
for (const [name, spec] of Object.entries(pkg[field] || {})) {
if (typeof spec === "string" && (spec.startsWith("file:") || spec.includes("release-assets"))) {
throw new Error(`${pkg.name} has non-portable ${field}.${name} spec: ${spec}`);
}
}
}
}View on GitHub (pinned to 322425c43b)
Solutions
- Sanity-check the tarball by hand: `tar -tzf <tarball> | head` — if that fails, the archive is corrupt; rebuild it.
- Confirm `tar` exists on PATH in the environment running the script (`which tar`); in slim Docker images install it (`apk add tar` / `apt-get install tar`).
- On macOS/BSD-tar issues, run under GNU tar (`gtar`) or the Node implementation the script could use (e.g., node-tar) if portable.
- If status is null, also log `result.error` — spawnSync puts the spawn failure there, not in stderr.
Example fix
// before
const result = spawnSync("tar", ["-xzf", tarballPath, "-C", workdir], { encoding: "utf8" });
if (result.status !== 0) {
throw new Error(`tar failed for ${tarballPath}: ${result.stderr || result.stdout || "unknown error"}`);
}
// after: surface the spawn error too
if (result.error || result.status !== 0) {
throw new Error(
`tar failed for ${tarballPath}: ${result.error?.message || result.stderr || result.stdout || "unknown error"}`,
);
} Defensive patterns
Strategy: try-catch
Validate before calling
import { execFileSync } from "node:child_process";
function tarballIntact(tarballPath) {
try {
execFileSync("tar", ["-tzf", tarballPath], { stdio: "ignore" });
return true;
} catch {
return false;
}
}
// assert tarballIntact(p) before extractJsonFromTarball(p, ...) Try / catch
try {
const pkg = extractJsonFromTarball(tarballPath, "package/dist/package.json");
} catch (err) {
if (/tar failed/.test(err.message)) {
// distinguish corrupt archive vs missing binary before retrying
if (!tarballIntact(tarballPath)) throw new Error(`corrupt tarball: ${tarballPath}`);
throw new Error(`tar unavailable or incompatible: ${err.message}`);
}
throw err;
} Prevention
- Verify tarballs with `tar -tzf` right after producing or downloading them.
- Ensure `tar` is installed in the runtime image (slim Docker images often omit it).
- Log `result.error` from spawnSync alongside stderr — spawn failures land there, not in the streams.
When it happens
Trigger: The tarball is truncated or not gzip data (interrupted `npm pack`, bad download/copy); `tar` is not on PATH (result.status is null, result.error set, message shows 'unknown error'); platform tar incompatibilities (BSD tar vs GNU tar flags); the temp extraction dir is unwritable.
Common situations: Verifying artifacts that were transferred between CI and a local machine; minimal Docker images lacking tar; macOS default bsdtar behaving differently from GNU tar; parallel runs colliding on tmp space.
Related errors
- Expected npm pack to produce ${tarballPath}
- Invalid semantic version: {value}
- Unsupported bump level: {level}
- Invalid release tag: {tag}
- ${command} failed with exit code ${result.status ?? "unknown
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/4392e4a4d92c9e35.
Report an issue: GitHub.