headroomlabs-ai/headroom · error · SystemExit

could not read {pkg_info_path} from {sdist.name}

Error message

could not read {pkg_info_path} from {sdist.name}

What it means

verify_sdist_license_files() looks up `<root>/PKG-INFO` in the sdist tarball and calls extractfile() on it. extractfile() returns None when the member exists but is not a regular file (directory, symlink, device). PKG-INFO must be a plain readable file in a valid sdist, so None indicates a malformed archive.

Source

Thrown at scripts/build_python_release_smoke.py:132

    if expected_line not in metadata.splitlines():
        raise SystemExit(f"{wheel.name} metadata missing {expected_line!r}")

    print(f"wheel metadata OK: {wheel.name} contains {native_members[0]}")


def verify_sdist_license_files(sdist: Path) -> None:
    with tarfile.open(sdist, "r:gz") as archive:
        names = set(archive.getnames())
        roots = {name.split("/", 1)[0] for name in names if "/" in name}
        if len(roots) != 1:
            raise SystemExit(f"expected one sdist root directory, found {sorted(roots)}")
        root = roots.pop()

        pkg_info_path = f"{root}/PKG-INFO"
        member = archive.getmember(pkg_info_path)
        fh = archive.extractfile(member)
        if fh is None:
            raise SystemExit(f"could not read {pkg_info_path} from {sdist.name}")
        pkg_info = fh.read().decode("utf-8")

    declared = []
    for line in pkg_info.splitlines():
        if not line.strip():
            break
        if line.startswith("License-File:"):
            declared.append(line.split(":", 1)[1].strip())

    if not declared:
        raise SystemExit(f"{sdist.name} declares no License-File entries")

    missing = [name for name in declared if f"{root}/{name}" not in names]
    if missing:
        raise SystemExit(
            f"{sdist.name} declares License-File entries missing from tarball: {missing}"
        )

View on GitHub (pinned to 322425c43b)

Solutions

  1. Check the member type: `tar -tvzf file.tar.gz | grep PKG-INFO` (should show `-` as the type, not `l` or `d`).
  2. Rebuild the sdist with maturin from a clean tree.
  3. If post-processing scripts rewrite the tarball, ensure they write PKG-INFO as a regular file.
Defensive patterns

Strategy: validation

Validate before calling

import tarfile

def pkg_info_readable(sdist_path: str, root: str) -> bool:
    with tarfile.open(sdist_path, "r:gz") as t:
        m = t.getmember(f"{root}/PKG-INFO")
        return m.isfile() and t.extractfile(m) is not None

Prevention

When it happens

Trigger: PKG-INFO present as a symlink or directory member; a tarball crafted by a non-standard tool that emits unusual member types; sparse/unsupported member encodings.

Common situations: Almost never seen with maturin-built sdists; appears with hand-rolled or post-processed tarballs, or archives mangled in transit.

Related errors


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