{"record":{"id":"885f716f2bdad1aa","repo":"headroomlabs-ai/headroom","slug":"could-not-read-pkg-info-path-from-sdist-name","errorCode":null,"errorMessage":"could not read {pkg_info_path} from {sdist.name}","messagePattern":"could not read (.+?) from (.+?)","errorType":"exception","errorClass":"SystemExit","httpStatus":null,"severity":"error","filePath":"scripts/build_python_release_smoke.py","lineNumber":132,"sourceCode":"    if expected_line not in metadata.splitlines():\n        raise SystemExit(f\"{wheel.name} metadata missing {expected_line!r}\")\n\n    print(f\"wheel metadata OK: {wheel.name} contains {native_members[0]}\")\n\n\ndef verify_sdist_license_files(sdist: Path) -> None:\n    with tarfile.open(sdist, \"r:gz\") as archive:\n        names = set(archive.getnames())\n        roots = {name.split(\"/\", 1)[0] for name in names if \"/\" in name}\n        if len(roots) != 1:\n            raise SystemExit(f\"expected one sdist root directory, found {sorted(roots)}\")\n        root = roots.pop()\n\n        pkg_info_path = f\"{root}/PKG-INFO\"\n        member = archive.getmember(pkg_info_path)\n        fh = archive.extractfile(member)\n        if fh is None:\n            raise SystemExit(f\"could not read {pkg_info_path} from {sdist.name}\")\n        pkg_info = fh.read().decode(\"utf-8\")\n\n    declared = []\n    for line in pkg_info.splitlines():\n        if not line.strip():\n            break\n        if line.startswith(\"License-File:\"):\n            declared.append(line.split(\":\", 1)[1].strip())\n\n    if not declared:\n        raise SystemExit(f\"{sdist.name} declares no License-File entries\")\n\n    missing = [name for name in declared if f\"{root}/{name}\" not in names]\n    if missing:\n        raise SystemExit(\n            f\"{sdist.name} declares License-File entries missing from tarball: {missing}\"\n        )\n","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/scripts/build_python_release_smoke.py#L114-L150","documentation":"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.","triggerScenarios":"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.","commonSituations":"Almost never seen with maturin-built sdists; appears with hand-rolled or post-processed tarballs, or archives mangled in transit.","solutions":["Check the member type: `tar -tvzf file.tar.gz | grep PKG-INFO` (should show `-` as the type, not `l` or `d`).","Rebuild the sdist with maturin from a clean tree.","If post-processing scripts rewrite the tarball, ensure they write PKG-INFO as a regular file."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import tarfile\n\ndef pkg_info_readable(sdist_path: str, root: str) -> bool:\n    with tarfile.open(sdist_path, \"r:gz\") as t:\n        m = t.getmember(f\"{root}/PKG-INFO\")\n        return m.isfile() and t.extractfile(m) is not None","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only build sdists with standard tooling (maturin/build); never rewrite tarballs by hand.","Validate archives after network transfer (`tar -tzf`) before verification steps.","If you repackage tarballs in CI, assert member types are regular files."],"tags":["python","sdist","tarfile","packaging"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}