headroomlabs-ai/headroom · error · SystemExit
{sdist.name} declares License-File entries missing from tarb
Error message
{sdist.name} declares License-File entries missing from tarball: {missing} What it means
verify_sdist_license_files() cross-checks every `License-File:` entry declared in PKG-INFO against the actual tarball members under the sdist root. An entry that is declared but not present in the archive fails the smoke test, because installing the package would reference license files that do not exist.
Source
Thrown at scripts/build_python_release_smoke.py:147
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}"
)
print(f"sdist License-File metadata OK: {declared}")
def venv_python(venv_dir: Path) -> Path:
if os.name == "nt":
return venv_dir / "Scripts" / "python.exe"
return venv_dir / "bin" / "python"
def smoke_install_wheel(wheel: Path, python_exe: str, expected_version: str) -> None:
with tempfile.TemporaryDirectory(prefix="headroom-python-smoke-") as tmp:
venv_dir = Path(tmp) / "venv"
run([python_exe, "-m", "venv", venv_dir])
smoke_python = venv_python(venv_dir)
View on GitHub (pinned to 322425c43b)
Solutions
- Compare declared entries with archive contents: `tar -tzf file.tar.gz | grep -i license`.
- Restore the declared file at the declared path and rebuild, or update the `license-files` list to the new filename.
- Check that no exclude rule in pyproject/Cargo config filters out the license file from the sdist.
Defensive patterns
Strategy: validation
Validate before calling
import tarfile
def license_entries_present(sdist_path: str, root: str) -> list[str]:
with tarfile.open(sdist_path, "r:gz") as t:
names = set(t.getnames())
declared = [
l.split(":", 1)[1].strip()
for l in t.extractfile(f"{root}/PKG-INFO").read().decode().splitlines()
if l.startswith("License-File:")
]
return [d for d in declared if f"{root}/{d}" not in names] Prevention
- Rename the license file and the license-files metadata in the same change.
- Check sdist exclude rules after touching packaging config.
- Build release sdists from a clean checkout so tracked files cannot go missing.
When it happens
Trigger: PKG-INFO declares `License-File: LICENSE` but the file was excluded from the sdist (missing on disk, excluded by include/exclude rules, or gitignored when building from a dirty tree).
Common situations: Renaming LICENSE to LICENSE.md without updating metadata; maturin sdist exclusion globs matching the license path; building from an exported tree that omitted the license file.
Related errors
- expected one sdist root directory, found {sorted(roots)}
- could not read {pkg_info_path} from {sdist.name}
- {sdist.name} declares no License-File entries
- {tool}: distributed via PyPI only; `pip install headroom-ai`
- archive did not contain expected member {member!r}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/cff1e0f3a056c147.
Report an issue: GitHub.