midudev/autoskills · error · Error

tar extract failed (status )

Error message

tar extract failed (status ${r.status})

What it means

extractTarball shells out to the system `tar -xzf` to unpack a downloaded repo tarball. If tar exits with a non-zero status, the script throws this error including the exit code. It indicates the archive is corrupt/incomplete or the destination is unusable — the script does not include tar's stderr unless --verbose is set.

Solutions

  1. Delete the cached tarball and re-run so it is re-downloaded (fixes corrupt/truncated archives)
  2. Re-run with --verbose to see tar's actual stderr
  3. Check free disk space and write permissions on destDir
  4. Test manually: `tar -xzf <tarball> -C <destDir>` to see the underlying error

Example fix

// before
await syncSkills({}); // stale corrupt tarball in cache
// after
rmSync(cacheDir, { recursive: true, force: true }); // clear cache, then
await syncSkills({});
Defensive patterns

Strategy: validation

Validate before calling

// validate the tarball before extracting
import { statSync } from "node:fs";
const st = statSync(tarFile);
if (st.size < 100) throw new Error(`tarball suspiciously small (${st.size}B); re-download`);
execSync(`tar -tzf ${tarFile} > /dev/null`); // integrity test; throws with real tar error

Try / catch

try {
  await syncSkills(opts);
} catch (err) {
  if (err.message.startsWith("tar extract failed")) {
    const status = err.message.match(/status (\d+)/)?.[1];
    console.error(`tar exited ${status}; clear cache and re-download, run with --verbose for tar stderr`);
  } else throw err;
}

Prevention

When it happens

Trigger: spawnSync("tar", ["-xzf", tarFile, "-C", destDir]) returns status !== 0 — truncated/corrupt download, disk full, no write permission in destDir, or `tar` failing on the gzip stream.

Common situations: A previous sync was interrupted leaving a partial tarball; the download failed silently earlier and the file is 0 bytes; destDir sits on a full or read-only filesystem; unusual tarball format from a non-GitHub source.

Related errors


AI-assisted analysis of midudev/autoskills@0ec725320d (2026-09-15). Data as JSON: /api/errors/0bf6d975a43502de. Report an issue: GitHub.

Appendix: source

Thrown at packages/autoskills/scripts/sync-skills.mjs:319

    // pulling in unrelated repo content.
    const filtered = pick === "" ? blobs.filter((t) => t.path === "SKILL.md") : blobs;
    for (const blob of filtered) {
      const rel = pick === "" ? blob.path : blob.path.slice(pick.length + 1);
      if (shouldSkipSkillFile(rel)) continue;
      const dest = join(destRoot, skillName, rel);
      await downloadRawFile(repo, sha, blob.path, dest);
    }
    found.set(skillName, join(destRoot, skillName));
  }
  return found;
}

function extractTarball(tarFile, destDir) {
  const r = spawnSync("tar", ["-xzf", tarFile, "-C", destDir], {
    stdio: FLAGS.verbose ? "inherit" : "pipe",
  });
  if (r.status !== 0) {
    throw new Error(`tar extract failed (status ${r.status})`);
  }
  const entries = readdirSync(destDir);
  const root = entries.find((e) => statSync(join(destDir, e)).isDirectory());
  if (!root) throw new Error(`Empty tarball in ${destDir}`);
  return join(destDir, root);
}

function runGit(args, label) {
  const result = spawnSync("git", args, {
    encoding: "utf-8",
    stdio: ["ignore", "pipe", "pipe"],
  });
  if (result.status !== 0) {
    throw new Error(`${label} failed: ${result.stderr.trim() || "unknown error"}`);
  }
  return result.stdout;
}

View on GitHub (pinned to 0ec725320d)