headroomlabs-ai/headroom · error · SystemExit
{wheel.name} metadata missing {expected_line!r}
Error message
{wheel.name} metadata missing {expected_line!r} What it means
verify_wheel() reads the wheel's METADATA and requires a `Version: <expected_version>` line matching the version the smoke test was invoked with. A mismatch means the wheel being verified was built from a different version of the source than the one being released.
Source
Thrown at scripts/build_python_release_smoke.py:115
native_members = [
name
for name in names
if name.startswith("headroom/_core") and Path(name).suffix.lower() in {".pyd", ".so"}
]
if not native_members:
raise SystemExit(f"{wheel.name} does not contain headroom/_core native extension")
metadata_members = [name for name in names if name.endswith(".dist-info/METADATA")]
if len(metadata_members) != 1:
raise SystemExit(
f"{wheel.name} should contain exactly one dist-info/METADATA, "
f"found {len(metadata_members)}"
)
metadata = archive.read(metadata_members[0]).decode("utf-8")
expected_line = f"Version: {expected_version}"
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")View on GitHub (pinned to 322425c43b)
Solutions
- Check the actual version: `unzip -p file.whl '*/METADATA' | grep ^Version`.
- Re-run the version bump (or verify-versions.py) and rebuild into a fresh out_dir so the wheel carries the current version.
- If the version is dynamic from Cargo.toml, make sure Cargo.toml `version` and pyproject/Cargo `version` agree before building.
Defensive patterns
Strategy: validation
Validate before calling
import zipfile
def wheel_version(wheel_path: str) -> str | None:
with zipfile.ZipFile(wheel_path) as z:
meta = next(n for n in z.namelist() if n.endswith(".dist-info/METADATA"))
for line in z.read(meta).decode().splitlines():
if line.startswith("Version:"):
return line.split(":", 1)[1].strip()
return None
# assert wheel_version(w) == expected_version before running the smoke Prevention
- Run verify-versions.py before building so every input agrees on the version.
- Bump the version once, then build once, then verify — never interleave.
- Keep dynamic version sources (Cargo.toml) in sync with pyproject.
When it happens
Trigger: Bumping the version in pyproject.toml after the wheel was built (stale wheel in out_dir); passing a different version argument to the smoke script than the one maturin stamped; dynamic version from Cargo.toml diverging from the expected version.
Common situations: See trigger scenarios.
Related errors
- output directory must be empty to avoid stale artifacts: {pa
- expected exactly one {pattern} in {out_dir}, found {len(matc
- {wheel.name} does not contain headroom/_core native extensio
- {wheel.name} should contain exactly one dist-info/METADATA,
- items_json must be JSON: {e}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/cc99b37b5b3903dc.
Report an issue: GitHub.