headroomlabs-ai/headroom · error · RuntimeError

Failed to extract archive: {e}

Error message

Failed to extract archive: {e}

What it means

Wraps tarfile.TarError raised while extracting the downloaded codebase-memory-mcp archive — i.e. the payload decompressed enough to open but failed during member extraction. Typical root causes: truncated download (connection cut mid-read so the gzip stream is short), corrupted bytes from a proxy, or a genuinely malformed tar built upstream. The chained TarError distinguishes this from the 'binary not found' (layout) and 'download failed' (transport) cases.

Source

Thrown at headroom/graph/installer.py:91

            raise ValueError(f"Invalid URL: {url}")

        with urlopen(url, timeout=60) as response:  # noqa: S310
            data = response.read()
    except Exception as e:
        raise RuntimeError(f"Failed to download codebase-memory-mcp from {url}: {e}") from e

    # Extract binary from tar.gz
    try:
        with tarfile.open(fileobj=io.BytesIO(data), mode="r:gz") as tar:
            for member in tar.getmembers():
                if member.name.endswith(CBM_BIN_NAME) or member.name == CBM_BIN_NAME:
                    member.name = target_path.name
                    tar.extract(member, CBM_BIN_DIR)
                    break
            else:
                raise RuntimeError("codebase-memory-mcp binary not found in archive")
    except tarfile.TarError as e:
        raise RuntimeError(f"Failed to extract archive: {e}") from e

    # Make executable
    target_path.chmod(target_path.stat().st_mode | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)

    # Verify
    try:
        from headroom._subprocess import run

        result = run(
            [str(target_path), "--version"],
            capture_output=True,
            text=True,
        )
        if result.returncode == 0:
            ver = result.stdout.strip()
            logger.info("Installed: %s", ver)
        else:
            logger.warning("Binary installed but version check failed")

View on GitHub (pinned to 322425c43b)

Solutions

  1. Simply retry the install — truncated transfers are usually transient; verify network stability first.
  2. Check disk space in CBM_BIN_DIR and /tmp; extraction needs headroom for the binary.
  3. Download the tar.gz manually, verify integrity (gzip -t file.tar.gz), and compare byte size to the GitHub asset size; if it differs, your proxy is truncating.
  4. Place a manually verified binary on PATH to bypass the installer entirely.

Example fix

# before
# RuntimeError: Failed to extract archive: unexpected end of data

# after: verify payload manually, then retry or bypass
$ curl -fL -o cbm.tar.gz "<GITHUB_RELEASE_URL>/<ver>/codebase-memory-mcp-linux-amd64.tar.gz"
$ gzip -t cbm.tar.gz && tar -xzf cbm.tar.gz -C ~/.local/bin/ && chmod +x ~/.local/bin/codebase-memory-mcp
Defensive patterns

Strategy: retry

Validate before calling

import gzip

def gz_intact(path: str) -> bool:
    try:
        with open(path, "rb") as f:
            gzip.GzipFile(fileobj=f).read()
        return True
    except (OSError, EOFError):
        return False

Try / catch

import time

for attempt in range(2):
    try:
        install_cbm()
        break
    except RuntimeError as e:
        if "Failed to extract" in str(e) and attempt == 0:
            time.sleep(3)  # truncated download — retry once
            continue
        raise

Prevention

When it happens

Trigger: urlopen succeeds but the response is cut off before the full body (aggressive 60s timeout on slow links, proxy buffer limits); disk-full during extraction; bit-flipped/corrupted cached download; upstream shipped a truncated release asset.

Common situations: Flaky networks in CI; downloads through filtering proxies that truncate large binaries; retries after partial failures reusing a bad cache.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/f53a8f97463f4be4. Report an issue: GitHub.